Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[python3] Puzzlekubus oplossen lukt niet...

Pagina: 1
Acties:

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
hoihoi

Members only:
Alleen zichtbaar voor ingelogde gebruikers. Inloggen


Mijn aanpak hierbij is de volgende aanpak:
  • Ik bereken voor elk vlak alle mogelijkheden op basis van de artiesten. De nummers van de artiesten heb ik in 2 arrays gezet. Voor elk vlak klopt de structuur; de nummers passen in elkaar en er zitten geen duplicaten tussen.
  • Elk vlak levert een setje oplossingen voor dat vlak op in een lijst. De correlatie tussen de vlakken wordt niet gecheckt; er kunnen dus nummers in bijvoorbeeld vlak a en b zitten. Dit gebeurt in de regels 40 tot en met 120. Niet heel mooi, maar ik weet ook niet 1-2-3 hoe ik dit minder lelijk kan coden. Wel check ik hier of elk vlak an sich klopt (met de ifjes in de inner loops)
  • Idealiter zou ik alle combinaties van alle vlakken achter elkaar zetten en daarna de constraints tussen de vlakken valideren. Dat is niet heel haalbaar, er zijn 1180*34*29*190*17*163 = 612560585200 combinaties mogelijk, dus ik moet wat prematuur optimaliseren.
  • Gevolg is dus dat ik vanaf r140 tot en met r165 een voor een alle vlakken combineer als deze geen constraint schenden. Mocht dat wel het geval zijn dan stop ik al. Constraints hierbij zijn de invulvelden die "over de rand" gaan. Deze constraints heb ik genummerd, en zijn hier te vinden:
    beatles kubus
    Constraint 1 is dus de verbinding tussen vlakken B en C.
  • Aan het eind controleer ik of de hele oplossing allemaal unieke nummers bevat. Dit doe ik door alle values uit mijn vlakken bij elkaar te kieperen in een list en een set. Als de lengte gelijk is dan zijn alle waarden uniek.
Mijn code:
Python:
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
stones= {(0,3,5),(0,4,6),(0,4,9),(1,1,2),(1,9,6),(2,2,5),(4,0,2),(6,2,7),(7,2,0),(7,3,3),(7,3,7),(7,4,8),(7,9,4),(8,1,2),(8,3,1),(8,8,3),(9,7,0)}
beatles={(0,3,9),(0,4,5),(0,7,6),(0,9,2),(1,0,4),(1,2,6),(1,6,8),(3,0,1),(3,0,8),(3,9,3),(4,3,0),(4,4,1),(4,4,6),(5,1,0),(5,9,4),(6,4,3),(6,4,8),(6,5,3),(6,6,0),(7,0,2),(8,2,5),(8,6,3),(8,7,1),(8,7,4),(9,3,5)}
oplossingen={"a":[], "b":[], "c":[], "d":[], "e":[], "f":[]}

def oplossing_contains_only_unique_values(o):
    values=list(o["vlak_a"].values())+list(o["vlak_b"].values())+list(o["vlak_c"].values())+list(o["vlak_d"].values())+list(o["vlak_e"].values())+list(o["vlak_f"].values())
    if len(values) == len(set(values)):
        return True
    return False
    
    
def pretty_print_oplossing(o): 
    print ("      {0}          ".format(o["vlak_a"]["ra2"][1]))
    print ("     {0}{1}{2}         ".format(o["vlak_a"]["ha1"][0],o["vlak_a"]["ha1"][1],o["vlak_a"]["ha1"][2]))
    print ("    {0}{1}A{2}{3}        ".format(o["vlak_a"]["ra4"][1],o["vlak_a"]["ra4"][0],o["vlak_a"]["ra5"][0],o["vlak_a"]["ra5"][1]))
    print ("     {0}{1}{2}         ".format(o["vlak_a"]["ha6"][0],o["vlak_a"]["ha6"][1],o["vlak_a"]["ha6"][2]))
    print ("  {0}   {1}   {2}   {3}  ".format(o["vlak_a"]["ra4"][1],o["vlak_a"]["ra7"][1],o["vlak_a"]["ra5"][1],o["vlak_a"]["ra2"][1]))
    
    print (" {0}{1}{2} {3}{4}{5} {6}{7}{8} {9}{10}{11} ".format(o["vlak_b"]["hb1"][0],o["vlak_b"]["hb1"][1],o["vlak_b"]["hb1"][2],o["vlak_c"]["hc1"][0],o["vlak_c"]["hc1"][1],o["vlak_c"]["hc1"][2],o["vlak_d"]["hd1"][0],o["vlak_d"]["hd1"][1],o["vlak_d"]["hd1"][2],o["vlak_e"]["he1"][0],o["vlak_e"]["he1"][1],o["vlak_e"]["he1"][2]))
    print ("{0}{1}B{2}{3}{4}C{5}{6}{7}D{8}{9}{10}E{11}{12}".format(o["vlak_e"]["re3"][1],o["vlak_b"]["vb1"][1],o["vlak_b"]["rb3"][0],o["vlak_b"]["rb3"][1],o["vlak_b"]["rb3"][2],o["vlak_c"]["rc3"][0],o["vlak_c"]["rc3"][1],o["vlak_c"]["rc3"][2],o["vlak_d"]["rd3"][0],o["vlak_d"]["rd3"][1],o["vlak_d"]["rd3"][2],o["vlak_e"]["re3"][0],o["vlak_e"]["re3"][1]))
    print (" {0}{1}{2} {3}{4}{5} {6}{7}{8} {9}{10}{11} ".format(o["vlak_b"]["hb4"][0],o["vlak_b"]["hb4"][1],o["vlak_b"]["hb4"][2],o["vlak_c"]["hc4"][0],o["vlak_c"]["hc4"][1],o["vlak_c"]["hc4"][2],o["vlak_d"]["hd4"][0],o["vlak_d"]["hd4"][1],o["vlak_d"]["hd4"][2],o["vlak_e"]["he4"][0],o["vlak_e"]["he4"][1],o["vlak_e"]["he4"][2]))

    print ("  {0}   {1}   {2}   {3}  ".format(o["vlak_b"]["rb5"][1],o["vlak_c"]["rc5"][1],o["vlak_d"]["rd5"][1],o["vlak_e"]["re5"][1]))
    print ("     {0}{1}{2}         ".format(o["vlak_f"]["hf1"][0],o["vlak_f"]["hf1"][1],o["vlak_f"]["hf1"][2]))
    print ("    {0}{1}F{2}{3}        ".format(o["vlak_b"]["rb5"][1],o["vlak_b"]["rb5"][2],o["vlak_d"]["rd5"][2],o["vlak_d"]["rd5"][1]))
    print ("     {0}{1}{2}         ".format(o["vlak_f"]["vf1"][2],o["vlak_e"]["re5"][2],o["vlak_f"]["vf2"][2]))
    print ("      {0}          ".format(o["vlak_e"]["re5"][1]))

# check of alle elementen in listOfValues uniek zijn
def valuesAreUnique(listOfValues):
    if len(listOfValues) == len(set(listOfValues)):
        return True
    else:
        return False
    
#ha1 = horizontaal , A1. etc. Hierbij geldt dan ook dat ra2 de rij is die over de ribbe gaat en die bij a2 begint. 
# vlakken B,D en E zijn qua opbouw gelijk, alleen andere invulling stones/beatles

# bereken alle mogelijke oplossingen voor vlak A en stop die in oplossingen["a"].
# De if's zitten bewust niet in de innerloop omdat dit de code HEEL veel trager maakt (Veel meer iteraties)... maar wel stukken leesbaarder.
for ha1 in beatles:          
    for ha6 in beatles:    
        if ha6 != ha1: 
            for va1 in beatles: 
                if ha1[0]==va1[0] and va1[2]== ha6[0] and valuesAreUnique([ha1,ha6,va1]):
                    for va3 in beatles: 
                        if va3[0] == ha1[2] and va3[2]== ha6[2] and valuesAreUnique([ha1,ha6,va1,va3]):
                            for ra2 in beatles:
                                if ra2[0] == ha1[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2]):
                                    for ra4 in beatles:
                                        if ra4[0] == va1[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2,ra4]):
                                            for ra5 in stones:
                                                    if ra5[0] == va3[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2,ra4,ra5]):
                                                        for ra7 in stones:                                                         
                                                            if ra7[0] == ha6[1]  and valuesAreUnique([ha1,ha6,va1,va3,ra2,ra4,ra5,ra7]):
                                                                    oplossing={"ha1":ha1, "ha6":ha6, "va1":va1, "va3":va3, "ra2":ra2, "ra4":ra4, "ra5":ra5, "ra7":ra7}    
                                                                    oplossingen["a"].append(oplossing)
                                                                                                                    
for hb1 in beatles:
    for hb4 in beatles:
        if valuesAreUnique([hb1,hb4]):
            for vb1 in beatles:
                if vb1[0] == hb1[0] and vb1[2]== hb4[0] and valuesAreUnique([hb1,hb4,vb1]):
                    for vb2 in stones:
                        if vb2[0] == hb1[2] and vb2[2]== hb4[2] and valuesAreUnique([hb1,hb4,vb1,vb2]):
                            for rb3 in stones:
                                if rb3[0] == vb2[1]  and valuesAreUnique([hb1,hb4,vb1,vb2,rb3]):
                                    for rb5 in stones:
                                        if rb5[0] == hb4[1]  and valuesAreUnique([hb1,hb4,vb1,vb2,rb3,rb5]):
                                            oplossing={"hb1":hb1, "hb4":hb4, "vb1":vb1, "vb2":vb2, "rb3":rb3, "rb5":rb5}
                                            oplossingen["b"].append(oplossing)

for hc1 in stones:
    for hc4 in beatles:
        if valuesAreUnique([hc1,hc4]):
            for vc1 in stones:
                if vc1[0] == hc1[0] and vc1[2]==hc4[0] and valuesAreUnique([hc1,hc4,vc1]):
                    for vc2 in stones:
                        if vc2[0] == hc1[2] and vc1[2]==hc4[2] and valuesAreUnique([hc1,hc4,vc1,vc2]):
                            for rc3 in beatles:
                                if rc3[0] == vc2[1]  and valuesAreUnique([hc1,hc4,vc1,vc2,rc3]):
                                    for rc5 in stones:
                                        if rc5[0] == hc4[1]  and valuesAreUnique([hc1,hc4,vc1,vc2,rc3,rc5]):    
                                            oplossing={"hc1":hc1, "hc4":hc4, "vc1":vc1, "vc2":vc2, "rc3":rc3, "rc5":rc5}
                                            oplossingen["c"].append(oplossing)

for hd1 in beatles:
    for hd4 in beatles:
        if valuesAreUnique([hd1,hd4]):
            for vd1 in beatles:
                if vd1[0] == hd1[0] and vd1[2]== hd4[0] and valuesAreUnique([hd1,hd4,vd1]):
                    for vd2 in beatles:
                        if vd2[0] == hd1[2] and vd2[2]== hd4[2] and valuesAreUnique([hd1,hd4,vd1,vd2]):
                            for rd3 in stones:
                                if rd3[0] == vd2[1]  and valuesAreUnique([hd1,hd4,vd1,vd2,rd3]):
                                    for rd5 in stones:
                                        if rd5[0] == hd4[1]  and valuesAreUnique([hd1,hd4,vd1,vd2,rd3,rd5]):
                                            oplossing={"hd1":hd1, "hd4":hd4, "vd1":vd1, "vd2":vd2, "rd3":rd3, "rd5":rd5}
                                            oplossingen["d"].append(oplossing)

for he1 in beatles:
    for he4 in beatles:
        if valuesAreUnique([he1,he4]):
            for ve1 in stones:
                if ve1[0] == he1[0] and ve1[2]== he4[0] and valuesAreUnique([he1,he4,ve1]):
                    for ve2 in stones:
                        if ve2[0] == he1[2] and ve2[2]== he4[2] and valuesAreUnique([he1,he4,ve1,ve2]):
                            for re3 in beatles:
                                if re3[0] == ve2[1]  and valuesAreUnique([he1,he4,ve1,ve2,re3]):
                                    for re5 in stones:
                                        if re5[0] == he4[1]  and valuesAreUnique([he1,he4,ve1,ve2,re3,re5]):
                                            oplossing={"he1":he1, "he4":he4, "ve1":ve1, "ve2":ve2, "re3":re3, "re5":re5}
                                            oplossingen["e"].append(oplossing)
                                                                                    
for hf1 in beatles:
        for vf1 in beatles:
            if valuesAreUnique([hf1,vf1]) and hf1[0] == vf1[0]:
                for vf2 in beatles:
                    if vf2[0]== hf1[2] and valuesAreUnique([hf1,vf1,vf2]):
                        oplossing={"hf1":hf1,"vf1":vf1,"vf2":vf2}
                        oplossingen["f"].append(oplossing)                                        
                    
print ("Oplossingen gevonden in A: {0}".format(len(oplossingen["a"]))) 
print ("Oplossingen gevonden in B: {0}".format(len(oplossingen["b"]))) 
print ("Oplossingen gevonden in C: {0}".format(len(oplossingen["c"]))) 
print ("Oplossingen gevonden in D: {0}".format(len(oplossingen["d"]))) 
print ("Oplossingen gevonden in E: {0}".format(len(oplossingen["e"]))) 
print ("Oplossingen gevonden in F: {0}".format(len(oplossingen["f"]))) 



# oplossingen per kubus waarbij de we dus de 6 vlakken matchen

# de vergelijkingen staan met plaatje en al hier:
# https://github.com/boudewijne/nbv/blob/master/nbv_2014/beatles-kubus.png

# we gaan nu kijken welke vlakken met elkaar matchen om een kubus te maken.
kubus_oplossingen=[]


for vlak_a in oplossingen["a"]:
    for vlak_b in oplossingen["b"]:
        # check 2
        if vlak_a["ra4"][2] == vlak_b["hb1"][1] :
            for vlak_c in oplossingen["c"]:
                # check 1 + 3
                if vlak_b["rb3"][2] == vlak_c["vc1"][1] and vlak_a["ra7"][2] == vlak_c["hc1"][1]: 
                    for vlak_d in oplossingen["d"]:
                    # check 4+5: (765k oplossingen)
                        if vlak_c["rc3"][2]==vlak_d["vd1"][1] and vlak_a["ra5"][2]==vlak_d["hd1"][1]: 
                            for vlak_e in oplossingen["e"]:
                                # check 6 + 7 (17604 oplossingen)
                                if vlak_a["ra2"][2]==vlak_e["he1"][1] and vlak_e["re3"][2]==vlak_b["vb1"][1]:
                                    #check 8 (4890 oplossingen)
                                    if vlak_d["rd3"][2] == vlak_e["ve1"][1]:
                                        for vlak_f in oplossingen["f"]:
                                            # check 9 (615 oplossingen)
                                            if vlak_b["rb5"][2] == vlak_f["vf1"][1]:
                                                # check 10 (78 oplossingen)
                                                if vlak_d["rd5"][2] == vlak_f["vf2"][1]:                                                            
                                                    # check 11 (18 oplossingen)
                                                    if vlak_c["rc5"][2] == vlak_f["hf1"][1]: 
                                                        oplossing={"vlak_a":vlak_a, "vlak_b":vlak_b, "vlak_c":vlak_c, "vlak_d":vlak_d, "vlak_e":vlak_e, "vlak_f":vlak_f}
                                                        kubus_oplossingen.append(oplossing)


print ("Kubus plossingen gevonden: {0}".format(len(kubus_oplossingen))) 

kubus_oplossingen=list(filter(lambda x: oplossing_contains_only_unique_values(x), kubus_oplossingen))

print ("Kubus plossingen gevonden met unieke waarden: {0}".format(len(kubus_oplossingen))) 

print_counter=1

for oplossing in kubus_oplossingen:
    print ("\nOplossing {}".format(print_counter))
    #pretty_print_oplossing(oplossing)
    print ("     {0}{1}{2}         ".format(oplossing["vlak_f"]["vf1"][2],oplossing["vlak_e"]["re5"][2],oplossing["vlak_f"]["vf2"][2]))
    print_counter+=1


Probleem is dat ik alleen maar oplossingen genereer waarin nummers meerdere malen worden gebruikt. Dat is niet de bedoeling (tenzij er maar 1 oplossing uit zou komen, dat zou ik wel best vinden :+).


Weet iemand waar dit fout gaat? Ik heb mijn constraints al eens gecheckt en genummerd (heck zelfs een plaatje in elkaar gepaint) maar ik zie het gewoon niet. Of maak ik hier een mega-denkfout? Ook lijkt mijn input-data gewoon prima te zijn.

  • sentiao
  • Registratie: November 2013
  • Laatst online: 07-06 13:02
Kan je de puzzelvraag wellicht wat meer toelichten?
"8. En nu iets met een vierkant en een kubus." wijst niet echt naar de Top1000.
En, moeten 2-cijferige top1000 noteringen wel een "0"-prefix krijgen?
Of ben ik hier te dom voor? :)


Nevermind, ik snap 'm...

[ Voor 23% gewijzigd door sentiao op 12-01-2015 17:07 ]


  • DRaakje
  • Registratie: Februari 2000
  • Niet online
Tja, deze lap code debuggen is nogal een karwei.

Zelf snap ik nog niet helemaal wat de input nou zou moeten zijn.

Ik zou het meer zien als een sudoku. Je moet het met logica oplossen en niet met bruteforce.
Waarbij je elke cel alle mogelijkheden heeft, en alle onmogelijkheden er steeds uit haalt, en als je niets vind, 1 van de opties uit kiest, en kijkt wat dat oplevert.

Dus meer elimineren aan de hand van logica.

Geen idee of dit werkt hier, maar zo zou ik er aan beginnen.

Misschien dat ik het vanavond eens probeer met jou input >_<, al heb ik geen idee hoe je aan de input komt komt.

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Nou ja qua bruteforce is het vrij simpel; het is goed te doen... het script kost een paar seconden op een i7 920, dus waarom verder optimaliseren?

De input: het zijn de noteringen van de beatles resp. stones uit de top2000 . Punt is wel dat ik me vandaag bedacht dat het exemplaar van 2014 wellicht beter is dan 2013 :P. (vroeger kwam de puzzle eerder uit en had je dus de top2000 van 1 jaar eerder moeten pakken)

[ Voor 12% gewijzigd door Boudewijn op 12-01-2015 21:10 ]


  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

De vraag gaat zelfs over de top 1000. Controleer even of die nummers uit het voorbeeld (Borsato, Meeuwis) ook op jouw lijst op de goede plek staan.

Ik ben al even aan het kijken of ik iets in PHP in elkaar kan knutselen....

  • Godlikev
  • Registratie: Mei 2007
  • Laatst online: 12-11 22:51
is er ergens een link met de betreffende lijst??

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Members only:
Alleen zichtbaar voor ingelogde gebruikers. Inloggen

[ Voor 3% gewijzigd door Boudewijn op 12-01-2015 22:01 ]


  • DRaakje
  • Registratie: Februari 2000
  • Niet online
@Boudewijn
Op dit moment krijg ik ook meerdere mogelijke antwoorden met de input die je gebruikt. Moet nog verifiëren met de hand of het inderdaad allemaal klopt. onder voorbehoud dus :)

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Nou ja ik krijg 0 antwoorden dus dat is helemaal niet goed, en vraag me af of iemand kan zien waar het hem in zit. Ik erger me helemaal kapot atm ;).

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Ik haak af, ik krijg het niet voor elkaar :( |:(

  • DRaakje
  • Registratie: Februari 2000
  • Niet online
Leuke puzzel, nog een paar bugs gevonden in mijn programma en krijg nu inderdaad ook geen oplossingen meer. Er zal nog wel ergens een foutje zitten. Morgen verder!

Had je al bedacht dat op F3 horizontaal nergens staat dat daar perse een Beatles of Rolling stones nummer moet komen?

[ Voor 27% gewijzigd door DRaakje op 13-01-2015 20:39 ]


  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Members only:
Alleen zichtbaar voor ingelogde gebruikers. Inloggen

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Weet je inmiddels al zeker dat de input klopt? Is er geen andere bron?

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Ik heb hem!!

Wil je de oplossing hebben?

  • DRaakje
  • Registratie: Februari 2000
  • Niet online
Nee!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Nee. Is mijn aanpak goed?

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Ik ben begonnen op een soort gelijke manier maar kwam er daarmee niet uit. Ik snap nog steeds niet zo goed waarom niet.

Daarna ben ik helemaal opnieuw begonnen met een nieuwe aanpak....

[edit]
Ik heb nog even naar je code gekeken en hij is helemaal goed, er zit alleen één klein foutje in. Als je die fixed dan heb je de oplossing.

Ik denk dat hetzelfde bij mij misging, een foutje is heel makkelijk gemaakt en lastig op te sporen. Ik heb het daarom iets `gestructureerder` aangepakt waardoor die fouten niet meer konden voorkomen en toen lukte het wel.

Als ik je foutje moet aanwijzen dan moet je het maar zeggen.

[ Voor 53% gewijzigd door emnich op 15-01-2015 08:17 ]


  • DRaakje
  • Registratie: Februari 2000
  • Niet online
Net eindelijk weer tijd gehad om er even aan te zitten. Na een half uurtje kleine foutjes opsporen de oplossing gevonden.

Uiteindelijk hoefde ik maar max 4 opties te bruteforcen, dus denk dat het uiteindelijk een best elegante oplossing is geworden die in 150 ms de oplossing vind.

Als ik zo kijk, dan vermoed ik dat deze met een beetje doorzettingsvermogen ook met de hand is op te lossen.

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Goed, en ik vind op regel 83 een logica foutje....

code:
1
                        if vc2[0] == hc1[2] and vc2[2]==hc4[2] and valuesAreUnique([hc1,hc4,vc1,vc2]):

Dat was vc1... maar nog steeds geen oplossing. Nog even verder prutsen dus.

@Draakje: yup, collega van me heeft het met de hand gedaan. Heel ziek.
Pagina: 1