Υλοποίηση Ακέραιου Μέρους

Ξεκίνησε από progmat, 01 Φεβ 2020, 07:22:18 ΜΜ

« προηγούμενο - επόμενο »

progmat

Καλησπέρα σας,

μπορούμε να υλοποιήσουμε στη ΓΛΩΣΣΑ δική μας συνάρτηση για το Α_Μ(); Δηλαδή να γράψουμε μια συνάρτηση που να κάνει την ίδια δουλειά με την Α_Μ() χωρίς φυσικά να χρησιμοποιήσουμε την Α_Μ(); Ευχαριστώ για το χρόνο σας!

akalest0s

Ίσως όχι η πιο κομψή λύση, still it gets the job done.
Κώδικας: Javascript
ΠΡΟΓΡΑΜΜΑ εκτός_υλοποίησηΣυνΑ_Μ
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: α
ΑΡΧΗ
  ΔΙΑΒΑΣΕ α
  ΓΡΑΨΕ custom_A_M(α)
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ 
! ==================
ΣΥΝΑΡΤΗΣΗ custom_A_M(α): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: i
  ΠΡΑΓΜΑΤΙΚΕΣ: α
ΑΡΧΗ
  i <- 0
  ΟΣΟ i <= Α_Τ(α) ΕΠΑΝΑΛΑΒΕ
    ΑΝ i < Α_Τ(α) ΚΑΙ i + 1 > Α_Τ(α) ΤΟΤΕ
      custom_A_M <- i
    ΤΕΛΟΣ_ΑΝ
    i <- i + 1
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ


υγ> αν δεν θες ούτε Α_Τ, τότε πάρε περιπτώσεις χωριστά "αν α=>0" και "αν α<0"
"Abstraction is not the first stage, but the last stage, in a mathematical development." MK
"I don't want to write about a high level thing, unless I fully understand about a low level thing" DK

ApoAntonis

@ akalestos,
αν το a είναι αρνητικός, επιστρέφεις θετική τιμή
και νομίζω ότι στην περίπτωση που έχουμε δεκαδικό μέρος μηδέν δεν δουλεύει σωστά


παίρνω δεδομένο ότι το ακέραιο μέρος το "χρησιμοποιούμε" μόνο για θετικούς:

i <- 0
ΟΣΟ ( i < a) ΕΠΑΝΑΛΑΒΕ
  i <-i+1
ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
ΑΝ i = a TOTE
  AM<- i
ΑΛΛΙΩΣ
  AM <- i-1
ΤΕΛΟΣ_ΑΝ

akalest0s

#3
Έχεις δίκιο. Η περίπτωση μηδενικού δεκαδικού μέρους, λύνεται απλά με ένα = στην πρώτη ανισότητα της Αν.
Τώρα πως μου ήρθε να γυρίζω πάντα θετικό αριθμό, δεν ξέρω! Τελείως άκυρο, δεν ξέρω τι σκεφτόμουν!  :D
Εύκολα διορθώνεται και αυτό, αλλά ο δικός σου κώδικας είναι καλύτερος, οπότε δεν μπαίνω στο κόπο να διορθώσω.
"Abstraction is not the first stage, but the last stage, in a mathematical development." MK
"I don't want to write about a high level thing, unless I fully understand about a low level thing" DK

akalest0s

#4
Παράθεση από: ApoAntonis στις 01 Φεβ 2020, 10:58:53 ΜΜ
παίρνω δεδομένο ότι το ακέραιο μέρος το "χρησιμοποιούμε" μόνο για θετικούς:

Γράφω το ίδιο και για αρνητικούς, αν το θέλει ο progmat (με εμφώλευση, φυσικά υπάρχουν και άλλοι τρόποι)
ΣΥΝΑΡΤΗΣΗ ΑΜ(α): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: i
  ΠΡΑΓΜΑΤΙΚΕΣ: α
ΑΡΧΗ
  i <- 0
  ΟΣΟ i <= Α_Τ(α) ΕΠΑΝΑΛΑΒΕ
    i <- i + 1
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΑΝ i = α ΤΟΤΕ
    AMv2 <- i
  ΑΛΛΙΩΣ
    ΑΝ α >= 0 ΤΟΤΕ
      AMv2 <- i - 1
    ΑΛΛΙΩΣ
      AMv2 <- -(i - 1) 
    ΤΕΛΟΣ_ΑΝ
  ΤΕΛΟΣ_ΑΝ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ
"Abstraction is not the first stage, but the last stage, in a mathematical development." MK
"I don't want to write about a high level thing, unless I fully understand about a low level thing" DK

George Eco

#5
Η δομή επανάληψης ΓΙΑ με βήμα 1.0 κάνει όλη τη δουλεία.

ΠΡΟΓΡΑΜΜΑ Εναλλακτική_προσέγγιση
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: α
ΑΡΧΗ
  ΔΙΑΒΑΣΕ α  ! α = πραγματικός αριθμός που εισάγεται
  ΓΡΑΨΕ ακεραιοποίηση(α) 
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

ΣΥΝΑΡΤΗΣΗ ακεραιοποίηση(α): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: ι
  ΠΡΑΓΜΑΤΙΚΕΣ: α, κ
ΑΡΧΗ
  ι <- 0
  κ <- 0.0 ! κ = μετρητής ακεραίων μονάδων
  ΓΙΑ κ ΑΠΟ 1.0 ΜΕΧΡΙ Α_Τ(α) ΜΕ_ΒΗΜΑ 1.0
    ι <- ι + 1 ! Το βήμα 1.0 αποκλείει το δεκαδικό μέρος
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

  ΑΝ α < 0.0 ΤΟΤΕ
    ι <- ι*-1 ! Επαναφορά προσήμου
  ΤΕΛΟΣ_ΑΝ
  ακεραιοποίηση <- ι ! Επιστροφή ακεραίου
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ


Πώς σας φαίνεται;

akalest0s

"Abstraction is not the first stage, but the last stage, in a mathematical development." MK
"I don't want to write about a high level thing, unless I fully understand about a low level thing" DK

George Eco

Δε σου κρύβω συνάδελφε πως δεν είδα στην αρχή τη πιο κάτω γραμμή του σχόλιού σου και την πάτησα!
Λέω, γιατί το αποκαλεί τελείως λάθος; Είχα κάνει και double check τα πάντα, όχι τίποτα άλλο.
Μου την έφερες!  ;D ;D ;D

gthal

#8
Παράθεση από: George Eco στις 02 Φεβ 2020, 07:01:53 ΠΜ
Πώς σας φαίνεται;
Ωραία και απλή η ιδέα!
Δύο παρατηρήσεις όμως:
1) Για τους αρνητικούς τι γίνεται;  πχ Α_Μ(-4)=-4  αλλά Α_Μ(-4.1)=-5, καθώς το Α_Μ(χ) είναι ο μικρότερος ακέραιος που δεν υπερβαίνει τον χ (εξαρτάται από την υλοποίηση βέβαια, αλλά και ο διερμηνευτής έτσι το υλοποιεί απ' ότι βλέπω). Οπότε χρειάζεται λίγο μαγείρεμα η τελευταία ΑΝ
2) Υπάρχει ζήτημα αποδοτικότητας βέβαια: έδωσα το 123456789.01 ας πούμε και δεν πήρα απάντηση ούτε σε ένα λεπτό... (είναι και λίγο παλιό το μηχάνημά μου βέβαια ...  :P )

Στον παρακάτω κώδικα αξιοποιώ την ιδέα σου επαναληπτικά ως εξής:
για τον 352,61 πχ :
διαιρώ μέχρι να γίνει μικρότερος του 1, για να μετρήσω τα ακέραια ψηφία (έστω cnt)
οπότε έχω τον 0,35261
στη συνέχεια πολ/σιάζω ξανά τόσες φορές (cnt=3) και κάθε φορά προσεγγίζω το καινούριο δεκαδικό κομμάτι με τη μέθοδό σου
πχ στην 1η επανάληψη έχω το 3,5261 και με τη μέθοδό σου φτάνω στο 3
στη 2η επανάληψη έχω το το 35,261  και αυτή τη φορά ξεκινώ από το 30 (δεκαπλασιάζοντας το προηγούμενο αποτέλεσμα) και φτάνω στο 35
στην 3η επανάληψη έχω το 352,61 και αυτή τη φορά ξεκινώ από το 350 (δεκαπλασιάζοντας το προηγούμενο αποτέλεσμα) και φτάνω στο 352

ΣΥΝΑΡΤΗΣΗ ΑΜ(y):ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: x, y ,cnt
  ΑΚΕΡΑΙΕΣ: result , c, r, k
ΑΡΧΗ
    x <- Α_Τ(y)
    ! διαιρώ επαναληπτικά για να μετρήσω τα ακέραια ψηφία
    cnt <- 0
    ΟΣΟ x>=1 ΕΠΑΝΑΛΑΒΕ
      x <- x/10
      cnt <- cnt+1
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ! ξαναπολ/σιάζω επαναληπτικά, προσεγγίζοντας το κάθε ψηφίο
    result <- 0
    ΓΙΑ c ΑΠΟ 1 ΜΕΧΡΙ cnt
      x <- x*10
      result <- result*10
      r <- result
      ΓΙΑ k ΑΠΟ result+1 ΜΕΧΡΙ x
        r <- r+1
      ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
      result <- r
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ! προσαρμογές για τους αρνητικούς
    ΑΝ y<0 ΤΟΤΕ
      result <- -result
      ΑΝ result<>y ΤΟΤΕ
        result <- result -1
      ΤΕΛΟΣ_ΑΝ
    ΤΕΛΟΣ_ΑΝ
    ΑΜ <- result
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ


edit: αυτό που λέω για την υλοποίηση της Α_Μ(χ) στο διερμηνευτή δεν είναι ακριβές. Μόλις τώρα είδα ότι υπάρχει επιλογή που εγώ έχω ενεργοποιημένη. Δε θυμάμαι αν υπάρχει οδηγία από το υπουργείο για την Α_Μ των αρνητικών
Φιλικά,
Γιώργος Θαλασσινός

progmat

Σας ευχαριστώ πολύ  όλους για την ενασχόληση!

George Eco

#10
Γιώργο καλησπέρα! Πολύ μου άρεσαν τσ σχόλιά σου!
Δείχνουν πως κατέχεις βαθιά γνώση στο αντικείμενο.

Όντως η Α_Μ() μπορεί να επιστρέψει δοθέντος -4.01 ως αποτέλεσμα το -5, ανάλογα την αντιμετώπιση του διερμηνευτή, αν και προσωπικά θεωρώ λάθος να επιστρέφει -5.
Επειδή είναι θεωητική η ΓΛΩΣΣΑ, σχεδιασμένη στο χαρτί από το Υπουργείο, κι εγώ μέχρι να βγεί κάποια οδηγία, ακολουθώ αυτό που ξεκάθαρα λέει το βιβλίο στο Κεφ 7.
Επιστρέφω μόνο το ακέραιο μέρος.

Τώρα για το θέμα αποδοτικότητας με τον αστρονομικό αριθμό, δέχομαι το σχόλιο. Σωστός! Μπορώ και καλύτερα.
Μεγάλη πρόκληση να μηχανευτώ κάτι, το μηχανεύτηκα, το κάνω debug, θα το αναρτήσω σύντομα!
Σημείωση: Η πρότασή σου, αν κι έχει ενδιαφέρον, δε βοήθησε πολύ. Εννοώ το πηλίκο δεν έκανε μεγάλη διαφορά και με προβλημάτισε.
Τρέξε τη για 123456789.01 δεν αποδίδει πολύ καλά. Κι είναι λογικό, βασιζόταν στη δική μου εκδοχή.
Οπότε Γιώργο ανέμενε, θα μοιραστώ κάτι ενδιαφέρον σύντομα.

George Eco

#11
Νομίζω τα κατάφερα!

ΠΡΟΓΡΑΜΜΑ Αποδοτική_υλοποποίηση_ΑΜ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: Υ
  ΠΡΑΓΜΑΤΙΚΕΣ: χ
ΑΡΧΗ
  ΔΙΑΒΑΣΕ χ
  Υ <- ΑΜ(χ) 
  ΓΡΑΨΕ Υ
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

! Λειτουργεί όπως η Α_Μ()
! ωστόσο -4.01 επιστρέφει 4
ΣΥΝΑΡΤΗΣΗ ΑΜ(χ): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: ΑΨ, δ, ψ, βάση_εις_τη_ψ, αχ
  ΠΡΑΓΜΑΤΙΚΕΣ: χ, χε
ΑΡΧΗ
! ΑΨ = Ακέραιο ψηφίο
!  δ = δύναμη
!  ψ = ψηφίο
!  βάση_εις_τη_ψ = 10 ^ Ψ
!  αχ = ακέραιο μέρος του χ
!   χ = Το αυθεντικό χ που δίνει ο χρήστης
!  χε = Το χ με το οποίο θα εργαστούμε
  αχ <- 0
  χε <- Α_Τ(χ) 
! 19 ψηφία αριθμός
  ΓΙΑ ψ ΑΠΟ 19 ΜΕΧΡΙ 1 ΜΕ_ΒΗΜΑ -1
    βάση_εις_τη_ψ <- 1 ! Αρχικοποίηση
    ΓΙΑ δ ΑΠΟ 0 ΜΕΧΡΙ ψ - 1 ! Χτίσιμο δύναμης βάσης 10
      ΑΝ δ = 0 ΤΟΤΕ
        βάση_εις_τη_ψ <- 1
      ΑΛΛΙΩΣ
        βάση_εις_τη_ψ <- βάση_εις_τη_ψ* 10
      ΤΕΛΟΣ_ΑΝ
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ΑΨ <- 0 ! Αρχικοποίηση
    ΟΣΟ χε/ βάση_εις_τη_ψ >= 1 ΕΠΑΝΑΛΑΒΕ
      ΑΨ <- ΑΨ + 1
      χε <- χε - βάση_εις_τη_ψ
      ! Πόσες φορές χωρά η βάση εις την Ψ
      ! Κι αφαίρεση αυτής, μία προς μία.
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    αχ <- αχ + ΑΨ* βάση_εις_τη_ψ
    ! Προσθήκη βάσης εις τη ψ επί τις φορές που περιέχεται
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΑΝ χ < 0 ΤΟΤΕ
    ! Διόρθωση προσήμου.
    αχ <- αχ*(-1)
  ΤΕΛΟΣ_ΑΝ
  ΑΜ <- αχ
  ! Απόδοση αποτελέσματος
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ


Η μεγαλύτερη δυσκολία είναι πως έχουμε πραγματικό, δε μπορούμε να χρησιμοποιήσουμε Α_Μ() οπότε και δε μπορούμε να χρησιμοποιήσουμε DIV και MOD.
Αλλά σα να μην έφτανε αυτό... η ύψωση σε δύναμη επιστρέφει πραγματικό ( για το ενδεχόμενο α^(1/ν) ) οπότε και δε μπορείς να υλοποιήσεις εύκολα δύναμη.

Με όλους αυτούς τους περιορισμούς, νόμιζα πως ίσως τελικά δε γινόταν να βγει αποδοτική λύση.
Αλλά ευχαριστώ για την υπόδειξη γιατί με προκάλεσε και με ενέπνευσε. Δε θα κοιμόμουν αν δε το έλυνα.
Λειτουργεί για δεκαεξαψήφιους ακεραίους δίχως πρόβλημα.

ΣΗΜΕΙΩΣΗ: Τη βελτιστοποιώ συνεχώς   Νομίζω πως τη βελτίωσα αρκετά. Έβαλα και σχόλια.

gthal

Παράθεση από: George Eco στις 04 Φεβ 2020, 09:00:36 ΜΜ
Όντως η Α_Μ() μπορεί να επιστρέψει δοθέντος -4.01 ως αποτέλεσμα το -5, ανάλογα την αντιμετώπιση του διερμηνευτή, αν και προσωπικά θεωρώ λάθος να επιστρέφει -5.
Επειδή είναι θεωητική η ΓΛΩΣΣΑ, σχεδιασμένη στο χαρτί από το Υπουργείο, κι εγώ μέχρι να βγεί κάποια οδηγία, ακολουθώ αυτό που ξεκάθαρα λέει το βιβλίο στο Κεφ 7.
Επιστρέφω μόνο το ακέραιο μέρος.
Συμφωνώ μαζί σου, στον προγραμματισμό, είναι μάλλον χρησιμότερο το Α_Μ(-3.5)=-3 και όχι -4 (που είναι ο μαθηματικός ορισμός)

Παράθεση από: George Eco στις 04 Φεβ 2020, 09:00:36 ΜΜ
Σημείωση: Η πρότασή σου, αν κι έχει ενδιαφέρον, δε βοήθησε πολύ. Εννοώ το πηλίκο δεν έκανε μεγάλη διαφορά και με προβλημάτισε.
Τρέξε τη για 123456789.01 δεν αποδίδει πολύ καλά. Κι είναι λογικό, βασιζόταν στη δική μου εκδοχή.
Γιατί λες ότι δεν αποδίδει; Μου δίνει αποτέλεσμα "αμέσως" (εμπειρικά το λέω, δεν έχω κάνει μετρήσεις βέβαια  ;) )

Ναι, η καινούρια λύση δίνει γρήγορα την απάντηση!
Δεν είχα πολύ χρόνο για να την καταλάβω αλλά αυτό που κάνεις με τις δυνάμεις του 10 ίσως μοιάζει με μια άλλη προσέγγιση που είχα προσπαθήσει και σου την παραθέτω μήπως την εξετάσεις (σόρυ που δεν έχει εξηγήσεις-σχόλια, αν χρειαστείς θα προσπαθήσω να αναλύσω)

ΣΥΝΑΡΤΗΣΗ ΑΜ(y):ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: x, y
  ΑΚΕΡΑΙΕΣ: x1, x2, step, result
ΑΡΧΗ
    x <- Α_Τ(y)
    x1 <- 1
    ΟΣΟ x1<x ΕΠΑΝΑΛΑΒΕ
      x1 <- x1*10
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ΑΝ x1=x ΤΟΤΕ
      result <- x1
    ΑΛΛΙΩΣ
      x1 <- x1 div 10
      step <- x1
      ΟΣΟ step>0 ΕΠΑΝΑΛΑΒΕ
        ΟΣΟ x1<x ΕΠΑΝΑΛΑΒΕ
          x1 <- x1 + step
        ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
        ΑΝ x1=x ΤΟΤΕ
          result <- x1
          step <- 0
        ΑΛΛΙΩΣ
          x1 <- x1 - step
          step <- step DIV 10
        ΤΕΛΟΣ_ΑΝ
      ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
      result <- x1
    ΤΕΛΟΣ_ΑΝ

    ΑΝ y<0 ΤΟΤΕ
      result <- -result
    ΤΕΛΟΣ_ΑΝ
    ΑΜ <- result
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ
Φιλικά,
Γιώργος Θαλασσινός

George Eco

#13
Γιατί λες ότι δεν αποδίδει; Μου δίνει αποτέλεσμα "αμέσως" (εμπειρικά το λέω, δεν έχω κάνει μετρήσεις βέβαια  ;) )

Αποδίδει έχεις δίκιο συνάδελφε. Κάτι λάθος συνέβη με τα copy paste μάλλον κι έτρεξα λάθος κώδικα. Το δοκίμασα τώρα και λειτουργεία καλά.

Για το νέο κώδικα:
Αχά! Μάλιστα! Πολύ ενδιαφέρουσα η προσέγγισή σου συνάδελφε!
Διαφέρει λίγο αλλά μου αρέσει το σκεπτικό της σταδιακής τομής κι ενίοτε ελέγχου ισότητας.

Θέλω να είμαι δίκαιος.
Έκανα beta και τις τρεις προσεγγίσεις (τη δική μου, τη νέα που μου έστειλες και την Α_Μ() )

Η ΑΜ() σκάει στο 11 ψηφίο.
Η δική μου προσέγγιση στο 17ο
Η δική σου στο 18ο!
Αυτό την κάνει καλύτερη κατά ένα ολόκληρο ψηφίο, γενονός που πρέπει να αναφερθεί!

17 ψηφία

Original :  12345678909876543

Δική μου: 12345678909876544

Δική σου: 12345678909876543 (!)

Α_Μ():      1575954752

=====================================

16 ψηφία

Original:   1234567890987654

Δική σου: 1234567890987654

Δική μου: 1234567890987654

Α_Μ():      1016588934

======================================

Η Α_Μ() for the record τη παλεύει μέχρι και 10 ψηφία, μετά το χάνει.

Η fusion εκδοχή με τη διαίρεση, λειτουργεί σα τη δική μου, με περισσότερη απόκλιση όμως:
Original:   12345678909876543
Δική μου: 12345678909876544
Δική σου: 12345678909876543
Fusion:     12345678909876541

Αλλά περίμενε, έχει κι άλλο!!!


99999999
Μέχρι 8 ψηφία όλα καλά η ΑΜ() και η δική σου κι η δική μου.

Στα 9 ψηφία η δική μουκι η fusion στρογγυλοποιούν στο 1000000000

Οπότε we got a winner!
Από την άλλη, θέλω να δω αν μπορώ να διορθώσω τη δική μου προσέγγιση.
Νομίζω δικαιούμαι την ευκαιρία μιας κι έκανα το testing.

I'll be back! :P :P :P


Πραγματικά  όταν γίνεται τέτοιου επιπέδου συζήτηση ενθουσιάζομαι!!!

bugman

#14
Υπάρχει και αυτή η λύση:
1. ΠΡΟΣΘΗΚΗ ΔΕΥΤΕΡΗΣ ΣΥΝΘΗΚΗΣ
ΟΣΟ c + b <= a ΚΑΙ c <> c + b ΕΠΑΝΑΛΑΒΕ
ΓΙΑ ΑΠΟΦΥΓΗ ΠΡΟΒΛΗΜΑΤΟΣ.
2. ΑΦΑΙΡΕΣΗ ΜΙΑΣ ΜΕΤΑΒΛΗΤΗΣ (ΔΟΥΛΕΥΕΙ ΜΕ ΤΡΕΙΣ ΤΩΡΑ)

ΠΡΟΓΡΑΜΜΑ bugman_A_Y
ΑΡΧΗ
  ΓΡΑΨΕ Π_Α_Μ(11111111111021200121.2) 
  ΓΡΑΨΕ Π_Α_Μ(13.12321) 
  ΓΡΑΨΕ Π_Α_Μ(1210023.12321) 
  ΓΡΑΨΕ Π_Α_Μ(3.92321) 
  ΓΡΑΨΕ Π_Α_Μ(3.92321*10^-30) 
  ΓΡΑΨΕ Π_Α_Μ(9.111292321) 
  ΓΡΑΨΕ Π_Α_Μ(123456789.01) 
  ΓΡΑΨΕ Π_Α_Μ(123123456456789.123) 
  ΓΡΑΨΕ Π_Α_Μ(123123000456789.123) 
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
ΣΥΝΑΡΤΗΣΗ Π_Α_Μ(a): ΠΡΑΓΜΑΤΙΚΗ
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: a, b, c
ΑΡΧΗ
  b <- 1
  a <- Α_Τ(a) 
  ΟΣΟ b < a ΕΠΑΝΑΛΑΒΕ
    b <- b*10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  c <- 0
  b <- b/10
  ΟΣΟ b >= 1 ΕΠΑΝΑΛΑΒΕ
    ΟΣΟ c + b <= a ΚΑΙ c <> c + b ΕΠΑΝΑΛΑΒΕ
      c <- c + b
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    b <- b/10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  Π_Α_Μ <- c
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ



1.11111111110212E19
13.00
1210023.00
3.00
0.00
9.00
123456789.00
123123456456789.00
123123000456789.00

bugman

Για αρνητικούς, όπου το -13.12321 δίνει -14

Αν βγάλουμε αυτές τις δυο γραμμές:
  ΑΛΛΙΩΣ_ΑΝ -c + a > 0 ΤΟΤΕ
    Π_Α_Μ <- -c - 1
τότε θα έχουμε -13

(χρειάστηκα μια μεταβλητή ακόμα για να κρατήσω το πρόσημο της αρχικής μεταβλητής)


ΠΡΟΓΡΑΜΜΑ bugman_A_Y2
ΑΡΧΗ
  ΓΡΑΨΕ Π_Α_Μ(11111111111021200121.2) 
  ΓΡΑΨΕ Π_Α_Μ(-13.12321) 
  ΓΡΑΨΕ Π_Α_Μ(1210023.12321) 
  ΓΡΑΨΕ Π_Α_Μ(3.92321) 
  ΓΡΑΨΕ Π_Α_Μ(3.92321*10^-30) 
  ΓΡΑΨΕ Π_Α_Μ(9.111292321) 
  ΓΡΑΨΕ Π_Α_Μ(123456789.01) 
  ΓΡΑΨΕ Π_Α_Μ(123123456456789.123) 
  ΓΡΑΨΕ Π_Α_Μ(123123000456789.123) 
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
ΣΥΝΑΡΤΗΣΗ Π_Α_Μ(a): ΠΡΑΓΜΑΤΙΚΗ
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: a, b, c
  ΛΟΓΙΚΕΣ: d
ΑΡΧΗ
  b <- 1
  d <- a >= 0
  a <- Α_Τ(a) 
  ΟΣΟ b < a ΕΠΑΝΑΛΑΒΕ
    b <- b*10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  c <- 0
  b <- b/10
  ΟΣΟ b >= 1 ΕΠΑΝΑΛΑΒΕ
    ΟΣΟ c + b <= a ΚΑΙ c <> c + b ΕΠΑΝΑΛΑΒΕ
      c <- c + b
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    b <- b/10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΑΝ d ΤΟΤΕ
    Π_Α_Μ <- c
  ΑΛΛΙΩΣ_ΑΝ -c + a > 0 ΤΟΤΕ
    Π_Α_Μ <- -c - 1
  ΑΛΛΙΩΣ
    Π_Α_Μ <- -c
  ΤΕΛΟΣ_ΑΝ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ



1.11111111110212E19
-14.00
1210023.00
3.00
0.00
9.00
123456789.00
123123456456789.00
123123000456789.00

gthal

Παράθεση από: George Eco στις 08 Φεβ 2020, 07:12:48 ΜΜ
.
.
.
Οπότε we got a winner!
Από την άλλη, θέλω να δω αν μπορώ να διορθώσω τη δική μου προσέγγιση.
Νομίζω δικαιούμαι την ευκαιρία μιας κι έκανα το testing.

I'll be back! :P :P :P
Τι έκατσες κι έκανες!!!
Μένω άφωνος ! 
Βεβαίως και δικαιούσαι! θα την περιμένω   ;)
Φιλικά,
Γιώργος Θαλασσινός

Γιαννούλης Γιώργος

Για να βάλω και γω το λιθαράκι μου, και επειδή η υλοποίηση του bugman μου άρεσε, άλλα επιστρέφει πραγματικό ενώ σκοπός μας είναι να γυρίζει ακέραιο.
Η βασική λογική της υλοποίησης είναι:

  • αρχικά του υπολογισμού των ψηφίων του αριθμού που δόθηκε
  • αφαιρεί τις δυνάμεις του 2 που απαιτούνται ώστε να σχηματιστεί ο ακέραιος αριθμος (αλα ρωσικά  :D ;D :D)
ΠΡΟΓΡΑΜΜΑ Ακεραιο_Μερος
ΑΡΧΗ
  ΓΡΑΨΕ Α_Μ_custom(11111111100121.2) 
  ΓΡΑΨΕ Α_Μ_custom(-13.12321) 
  ΓΡΑΨΕ Α_Μ_custom(1210023.12321) 
  ΓΡΑΨΕ Α_Μ_custom(3.92321) 
  ΓΡΑΨΕ Α_Μ_custom(3.92321*10^-30) 
  ΓΡΑΨΕ Α_Μ_custom(9.111292321) 
  ΓΡΑΨΕ Α_Μ_custom(123456789.01) 
  ΓΡΑΨΕ Α_Μ_custom(123123456456789.123) 
  ΓΡΑΨΕ Α_Μ_custom(123123000456789.123) 
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

ΣΥΝΑΡΤΗΣΗ Α_Μ_custom(χ): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: δυναμη, προσημο, αμ
  ΠΡΑΓΜΑΤΙΚΕΣ: χ, χ_προσωρινο
ΑΡΧΗ
  !Ευρεση προσήμου
  προσημο <- 1
  ΑΝ χ < 0 ΤΟΤΕ
    προσημο <- -1
  ΤΕΛΟΣ_ΑΝ
  χ_προσωρινο <- χ*προσημο

  !Υπολογισμός μέγιστης δύναμης του 2 που θα χρειαστούμε
  δυναμη <- 0
  ΟΣΟ 2^δυναμη <= χ_προσωρινο ΕΠΑΝΑΛΑΒΕ
    δυναμη <- δυναμη + 1
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

  αμ <- 0
  ΓΙΑ δυναμη ΑΠΟ δυναμη ΜΕΧΡΙ 0 ΜΕ_ΒΗΜΑ -1
    ΑΝ χ_προσωρινο >= 2^δυναμη ΤΟΤΕ
      !Επειδή η ^ επιστρέφει πραγματικό και θέλουμε ακέραιο
      !και δεν μπορούμε να χρησιμοποιήσουμε την Α_Μ
      αμ <- αμ + εις_την(2, δυναμη) 
      χ_προσωρινο <- χ_προσωρινο - 2^δυναμη
    ΤΕΛΟΣ_ΑΝ
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

  αμ <- αμ*προσημο
        !Επειδή η υλοποίηση γίνεται με τον μαθηματικό ορισμό για αρνητικές τιμές
  ΑΝ προσημο = -1 ΚΑΙ αμ <> χ ΤΟΤΕ
    αμ <- αμ - 1
  ΤΕΛΟΣ_ΑΝ
  Α_Μ_custom <- αμ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ

!Υπολογίζει τη δύναμη βαση^εκθετης αλλά επιστρέφει ακέραιο, χωρίς χρηση Α_Μ
ΣΥΝΑΡΤΗΣΗ εις_την(βαση, εκθετης): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: βαση, εκθετης, γινομενο
ΑΡΧΗ
  γινομενο <- 1
  ΓΙΑ εκθετης ΑΠΟ εκθετης ΜΕΧΡΙ 1 ΜΕ_ΒΗΜΑ -1
    γινομενο <- γινομενο*βαση
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  εις_την <- γινομενο
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ

bugman

#18
Γιαννούλης Γιώργος, δουλεύει μεν αλλά με περιορισμούς πχ στο

Η ΓΡΑΨΕ Α_Μ_custom(11111111100121.2*10^10) δίνει ότι να είναι (6371445259360010240) ενώ η αρχική δική μου δίνει το ακέραιο μέρος (ως πραγματική) 1.11111111110212E29

Παρακάτω έχω αφαιρέσει την ΣΥΝΑΡΤΗΣΗ εις_την(βαση, εκθετης): ΑΚΕΡΑΙΑ
και έχω βάλει έναν πίνακα εισ_την[100]
Έτσι έχουμε το λεγόμενο look up table (ή πίνακα αντιστοιχιών). Αν είχαμε γενικές (σφαιρικές) μεταβλητές ο πίνακας θα μπορούσε να ήταν "μόνιμος", έτσι σε κάθε κλήση θα κερδίζαμε σε ταχύτητα. Κάτι τέτοιο δεν μπορεί να γίνει στη γλώσσα. Θα πρέπει να το δίνουμε σαν παράμετρο, και θα γίνεται αντιγραφή όλου του πίνακα. Οπότε ξεχνάμε το πίνακα να είναι φτιαγμένος μια φορά. Καθώς υπολογίζουμε τη μέγιστη δύναμη παράγουμε τα στοιχεία του πίνακα που θέλουμε. Έχουμε έναν αρκετά μεγάλο πίνακα για να παρέχουμε όλα τα στοιχεία.

ΠΡΟΓΡΑΜΜΑ Ακεραιο_Μερος2
ΑΡΧΗ
  ΓΡΑΨΕ Α_Μ_custom(11111111100121.2) 
  ΓΡΑΨΕ Α_Μ_custom(-13.12321) 
  ΓΡΑΨΕ Α_Μ_custom(1210023.12321) 
  ΓΡΑΨΕ Α_Μ_custom(3.92321) 
  ΓΡΑΨΕ Α_Μ_custom(3.92321*10^-30) 
  ΓΡΑΨΕ Α_Μ_custom(9.111292321) 
  ΓΡΑΨΕ Α_Μ_custom(123456789.01) 
  ΓΡΑΨΕ Α_Μ_custom(123123456456789.123) 
  ΓΡΑΨΕ Α_Μ_custom(123123000456789.123) 
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

ΣΥΝΑΡΤΗΣΗ Α_Μ_custom(χ): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: δυναμη, προσημο, αμ, εισ_την[100] 
  ΠΡΑΓΜΑΤΙΚΕΣ: χ, χ_προσωρινο
ΑΡΧΗ
 !Ευρεση προσήμου
  προσημο <- 1
  ΑΝ χ < 0 ΤΟΤΕ
    προσημο <- -1
  ΤΕΛΟΣ_ΑΝ
  χ_προσωρινο <- χ*προσημο

 !Υπολογισμός μέγιστης δύναμης του 2 που θα χρειαστούμε
  δυναμη <- 0
  εισ_την[δυναμη + 1] <- 1
  ΟΣΟ 2^δυναμη <= χ_προσωρινο ΕΠΑΝΑΛΑΒΕ
    δυναμη <- δυναμη + 1
    εισ_την[δυναμη + 1] <- εισ_την[δυναμη]*2
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

  αμ <- 0
  ΓΙΑ δυναμη ΑΠΟ δυναμη ΜΕΧΡΙ 0 ΜΕ_ΒΗΜΑ -1
    ΑΝ χ_προσωρινο >= 2^δυναμη ΤΟΤΕ
 !Επειδή η ^ επιστρέφει πραγματικό και θέλουμε ακέραιο
 !και δεν μπορούμε να χρησιμοποιήσουμε την Α_Μ
      αμ <- αμ + εισ_την[δυναμη + 1] 
      χ_προσωρινο <- χ_προσωρινο - 2^δυναμη
    ΤΕΛΟΣ_ΑΝ
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

  αμ <- αμ*προσημο
 !Επειδή η υλοποίηση γίνεται με τον μαθηματικό ορισμό για αρνητικές τιμές
  ΑΝ προσημο = -1 ΚΑΙ αμ <> χ ΤΟΤΕ
    αμ <- αμ - 1
  ΤΕΛΟΣ_ΑΝ
  Α_Μ_custom <- αμ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ



Και η γραμμή
      χ_προσωρινο <- χ_προσωρινο - 2^δυναμη


μπορεί να γίνει:
      χ_προσωρινο <- χ_προσωρινο - εισ_την[δυναμη + 1]


εδώ αντί για 6371445259360010240 γυρίζει -1
στο ΓΡΑΨΕ Α_Μ_custom(11111111100121.2*10^10)

bugman

#19
Με μια δεύτερη ματιά, ούτε ο πίνακας χρειάζεται:
Διόρθωσα και το λάθος του -1 στο τελικό αριθμό (υπάρχει μια Αν ακόμα δείτε το πρόγραμμα)

Νεα Διόρθωση για το ΓΡΑΨΕ Α_Μ_custom(-4.92321)  (τώρα δίνει -5 και όχι -6).


Αφαίρεσα μια μεταβλητή (η Σούμα έγινε Δύναμη και αφαιρέθηκε η παλιά Δύναμη).

ΠΡΟΓΡΑΜΜΑ Ακεραιο_Μερος3_2
ΑΡΧΗ
  ΓΡΑΨΕ Α_Μ_custom(11111111100121.2) 
  ΓΡΑΨΕ Α_Μ_custom(-13.12321) 
  ΓΡΑΨΕ Α_Μ_custom(1210023.12321) 
  ΓΡΑΨΕ Α_Μ_custom(-4.92321) 
  ΓΡΑΨΕ Α_Μ_custom(3.92321*10^-30) 
  ΓΡΑΨΕ Α_Μ_custom(9.111292321) 
  ΓΡΑΨΕ Α_Μ_custom(123456789.01) 
  ΓΡΑΨΕ Α_Μ_custom(123123456456789.123) 
  ΓΡΑΨΕ Α_Μ_custom(123123000456789.123) 
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

ΣΥΝΑΡΤΗΣΗ Α_Μ_custom(χ): ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: προσημο, αμ, δύναμη
  ΠΡΑΓΜΑΤΙΚΕΣ: χ, χ_προσωρινο
ΑΡΧΗ
 !Ευρεση προσήμου
  προσημο <- 1
  ΑΝ χ < 0 ΤΟΤΕ
    προσημο <- -1
  ΤΕΛΟΣ_ΑΝ
  χ_προσωρινο <- χ*προσημο

  δύναμη <- 1
  ΟΣΟ δύναμη <= χ_προσωρινο ΕΠΑΝΑΛΑΒΕ
    δύναμη <- δύναμη*2
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

  αμ <- 0
  ΟΣΟ δύναμη > 1 ΕΠΑΝΑΛΑΒΕ
    ΑΝ χ_προσωρινο >= δύναμη ΤΟΤΕ
 !Επειδή η ^ επιστρέφει πραγματικό και θέλουμε ακέραιο
 !και δεν μπορούμε να χρησιμοποιήσουμε την Α_Μ
      αμ <- αμ + δύναμη
      χ_προσωρινο <- χ_προσωρινο - δύναμη
    ΤΕΛΟΣ_ΑΝ
    δύναμη <- δύναμη div 2
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΑΝ χ_προσωρινο >= 1 ΤΟΤΕ
    αμ <- αμ + 1
  ΤΕΛΟΣ_ΑΝ
  αμ <- αμ*προσημο
 !Επειδή η υλοποίηση γίνεται με τον μαθηματικό ορισμό για αρνητικές τιμές
  ΑΝ προσημο = -1 ΚΑΙ αμ <> χ ΤΟΤΕ
    αμ <- αμ - 1
  ΤΕΛΟΣ_ΑΝ
  Α_Μ_custom <- αμ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ