Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Mein erstes Programm
BeitragVerfasst: 21 Dez 2016, 12:16 
Offline
Nuby

Registriert: 11 Dez 2016, 22:54
Beiträge: 2
Hallo zusammen.
Vor nicht allzulanger Zeit habe ich angefangen mich mit Computerprogrammierung zu beschäftigen.
Ruby war und ist die Sprache meiner Wahl.
Auf einem Geocacher Treffen empfahl mir ein bekannter probier doch mal aus dieses Rätsel mithilfe eines Programmes zu lösen.
Gesagt getan aber mein Programm braucht eine halbe ewigkeit und ich finde es sieht sogar echt unübersichtlich aus.
Trotzdem liefert es das richtige ergebniss.
Jetzt meine Frage.
Könnt ihr euch das mal ansehen und mir ein paar Tips zur übersichtlichkeit und vereinfachung meines Codes geben ?

Ach ja hier mal die Aufgabenstellung:
Multipliziere zwei dreistellige Zahlen schriftlich miteinander.
Die zwischenschritte müssen dabei ebenfalls dreistellig sein und das Ergebniss muss fünf stellen haben.
Etwa so:
ABC * DEF
-------------------
GHI
JKL
MNO
-------------------
PQRST

Besonderheit :
Alle Ziffern von 0 bis 9 dürfen nur jeweils zweimal vorkommen !


Hier mal mein Code :



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

vorgabe = [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9] # Dieser Bereich dient
vorgabezwei = [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9] # dazu, zu ermitteln
multiplikatoren = vorgabezwei.permutation(6).to_a # welche Multiplikatoren
multiplikatoren = multiplikatoren.uniq! # in Frage kommen



multiplikatoren.each do
|a|
b =a[0]*100 # hier entsteht der erste Multiplikator
c =a[1]*10
d =a[2]
multeins = b+c+d
e = a[3]*100 # hier entsteht der zweite Multiplikator
f = a[4]*10
g = a[5]
multzwei = e+f+g
ergeb = multeins.to_i*multzwei.to_i # Ergebniss der beiden Multiplikatoren
if ergeb <= 99999
stepa = multeins*a[3] # Dies sind die einzelnen
stepb = multeins*a[4] # Zwischenschritte einer
stepc = multeins*a[5] # Schriftlichen Multiplikation
if stepa <= 999 and stepb <=999 and stepc <= 999 # Wenn die einzellnen Zwischenschritte
vergleich = []
vergleich << b/100 # Zerlegung der Zwischenschritte in einzelne Ziffern
vergleich << c/10
vergleich << d
vergleich << e/100
vergleich << f/10
vergleich << g
y = 0
5.times do
x = ergeb.to_s[y] # Die einzelnen Ziffern werden in einem Array abgelegt
vergleich << x.to_i
y +=1
end
y = 0
3.times do
x = stepa.to_s[y]
vergleich << x.to_i
y +=1
end
y = 0
3.times do
x = stepb.to_s[y]
vergleich << x.to_i
y +=1
end
y = 0
3.times do
x = stepc.to_s[y]
vergleich << x.to_i
y +=1
end
if vorgabe == vergleich.sort # Das oben erstellte Array wird mit der Vorgabe verglichen
puts multeins
puts multzwei
puts stepa # Schlu��endlich das Ergebniss und die einzelnen Zwischenschritte
puts stepb
puts stepc
puts ergeb
end
end
end
#p stepa
#p stepb
#p stepc
end

#p multeins
#p multzwei



Tausend dank und weiter So !

Grüße an alle !


Zuletzt geändert von Jadefalke am 22 Dez 2016, 20:02, insgesamt 1-mal geändert.

Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Mein erstes Programm
BeitragVerfasst: 22 Dez 2016, 09:45 
Offline
Schüler

Registriert: 06 Mai 2008, 12:42
Beiträge: 22
Wohnort: München
vorgabezwei.permutation(6).to_a liefert ein Array von gut 13 Millionen Einträgen, über das Du dann iterierst. Die Berechnung des Arrays dauert schon eine Weile, und dass ein Loop mit so vielen Iterationen nicht von heut' auf vorgestern fertig wird, dürfte auch nicht überraschen.....

Ach ja, und was die Verständlichkeit angeht: Ein paar Kommentare in Deinem Code würden auch nicht schaden.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Mein erstes Programm
BeitragVerfasst: 22 Dez 2016, 20:05 
Offline
Nuby

Registriert: 11 Dez 2016, 22:54
Beiträge: 2
Ich habe mal ein paar Komentare angefügt.
Ich hoffe mal das genügt zur erklärung was ich da mache.

Das Problem mit der Permutation ist mir bekannt, leider hat meine andere Variante zu keinem Ergebniss geführt.

Deswegen habe ich ja auch hier gefragt ob es da eine bessere und einfachere möglichkeit für gibt.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Mein erstes Programm
BeitragVerfasst: 23 Dez 2016, 09:09 
Offline
Schüler

Registriert: 06 Mai 2008, 12:42
Beiträge: 22
Wohnort: München
Jadefalke hat geschrieben:
Ich habe mal ein paar Komentare angefügt.
Ich hoffe mal das genügt zur erklärung was ich da mache.

Das Problem mit der Permutation ist mir bekannt, leider hat meine andere Variante zu keinem Ergebniss geführt.


Du willst offenbar *alle* Lösungen für das Problem finden. Das dauert natürlich. Du kannst die Verarbeitung ein wenig beschleunigen, in dem Du nach jedem Zwischenergebnis - zum Beispiel wenn Du zunächst PQRST ermittelst - schon prüfst, ob die Bedingung, dass jede Ziffer maximal 2 mal vorkommt, noch erfüllt ist, und wenn nicht, gleich mit der nächsten Iteration weitermachst.

Zum Prüfen dieser Bedingung würde ich ein Array 'occurances' mit 10 Elementen anlegen, worin occurances[i] angibt, wie oft Du die Ziffer i schon verbraucht hast.

Ausserdem kannst Du die Zahl der Kombinationen von vornherein reduzieren. Beispielsweise kann A und D nicht gleichzeitig 9 sein. Allgemeiner: Wenn A größer als 4 ist, muss D kleiner als 4 sein.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Mein erstes Programm
BeitragVerfasst: 17 Feb 2017, 15:06 
Offline
Novize

Registriert: 19 Jan 2017, 10:36
Beiträge: 19
Hi,

ich habe mich interessehalber auch mal an dem Problem versucht:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def get_factors
solutions, factors = [], {}
100.upto(999) do |i|
d1 = i.digits.reverse

100.upto(999) do |j|
# pruefe auf exitierende faktoren
# (in umgekehrter reihenfolge)
next if factors[j.to_s+i.to_s]

# ergebnis pruefen
e = i*j
next if !e.between?(10000, 99999)

d2 = j.digits.reverse
# ziffern pruefen
condition = true
digit_count = Hash.new(0)
(d1+d2).each do |digit|
if (digit_count[digit]+=1) > 2
condition = false
break
end
end

next if !condition

# einzelschritte pruefen
sum, condition = 0, true
d2.each do |mul|
sum += mul*i
if !sum.between?(100,999)
condition = false
break
end
end

next if !condition

# faktoren f��r schnellen Zugriff speichern,
# um auf doppelte zu pruefen
factors[i.to_s+j.to_s] = true

# und ab in die loesungen
solutions << [i,j,e]
end
end
return solutions
end

t0 = Time.now
solutions = get_factors
t = Time.now-t0

puts "#{solutions.length} Loesungen gefunden. Dauer: #{t}"
=> 6314 Loesungen gefunden. Dauer: 0.78175915

Das geht ja von der Laufzeit noch, aber sind ja auch nur kleine Zahlen :D
Ich versuche, die Schleifen möglichst früh abzubrechen, sobald eine Bedingung nicht erfüllt ist.
Mal sehen, wie ich das mit dem eleminieren von doppelten Lösungen am besten mache.
Diese Lösung kommt ohne zusätzlichen Speicher aus, ausser für das Speichern der Lösungen und
konstant grosse Zwischenspeicher für die Ziffern.
Btw.: ich bin bei der Aufgabenstellung davon ausgegangen, daß jede Ziffer in beiden Faktoren
zusammen insgesamt nur zweimal existieren darf.
Wenn die Ziffern jeweils in den Zwischenergebnissen und dem Ergebnis UND in den Faktoren nur 2 mal vorkommen
dürfen, müsste ich extra-Prüfungen vornehmen.
Edit:
Doppelte Faktoren prüfe ich nun mit einem Hash, in dem die Faktoren als Keys gespeichert sind.
Damit steigt der Speicherbedarf, aber die Laufzeit nur unerheblich.


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 6 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
cron