Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.
Nástěnka
❗22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
❗04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
❗23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.
Nejste přihlášen(a). Přihlásit
Zdravím,mám tu zajímavý programátorský oříšek. Nebo ne spíš ani tak programátorský ale matematicko-logický. Vysvětlení sem napíšu, abyste zbytečně nebádali : nějak došlo k tomu, že výsledkem třídící funkce v bloku("funkci") select není permutace písmen "ablon", ale inverzní permutace těchto písem- což dává nesprávný výsledek
Otázka tedy není co, se stalo, ale proč? (ostatně tam mám část spravne, která vrací invertovanou invertovanou permutaci písmen, která je správná)
Mám pětici písmen ALBON, a 120 možných permutací a znich vybrat ty, které odpovídají mé podmínce (daný znak se nevyskytuje na konkrétních pozicích). Kódování jsem si zjednodušil jakousi transpozicí-záměnou , že místo permutací slov (ABLON,NOLBA...) permutuji pořadí těchto písmen (1,2,3,4,5,54321) a to mi dovolilo elegantně pojmenovat argumenty třídící funkce přímo těmi písmeny a.l,b,o.n.
Přesto ale pořád nechápu, že i tak ta chyba (vrací invertovanou permutaci) vznikla. Sémanticky mám pocit, že to je správně. Nevím proč, ale vím, že to je chybné(hned 3.4,5, zápis tu permutaci invertuje a vrac správné výsledky). Možná něco přehlížím, co je pod nosem.
Jen pro zajímavost, tentýž kód "spatně" je ve dvou variantách a "spravne" ve třech, funkčně stejný, ale pro zajímavost demostruje tři různé způsoby transpozice , nebo ani ne transpozice, ale nalezení inverzní permutace (seřazení pole, seřazení hashe, hledání pořadí prvku)
(Jenom poznámka, první položka LAOBN shodou okolností je stejná pokaždé, tak podle ní se neorientujte)
#spatne: j=[1,2,3,4,5].permutation.select{|a,l,b,o,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)} .map(){|a|a.join.tr("12345","ALBON")}; p j.size; p j; 17 #=> ["LAOBN", "LANBO", "LBAON", "LBANO", "LBONA", "LBNOA", "LOABN", "LONBA", "LNABO", "LNOBA", "BAONL", "BANOL", "BOANL", "BNAOL", "NAOBL", "NBAOL", "NOABL"] j=[1,2,3,4,5].permutation.select{|a,l,b,o,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)}. map(){|a|a.map{|x|"ALBON".chars[x-1]}.join}; p j.size;p j; 17 #=> ["LAOBN", "LANBO", "LBAON", "LBANO", "LBONA", "LBNOA", "LOABN", "LONBA", "LNABO", "LNOBA", "BAONL", "BANOL", "BOANL", "BNAOL", "NAOBL", "NBAOL", "NOABL"] #spravne: j=[1,2,3,4,5].permutation.select{|a,l,b,o,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)}. map(){|a|a.zip("ALBON".chars).sort.to_h.values.join}; p j.size;p j; 17 #=> ["LAOBN", "LAONB", "BALON", "BALNO", "NALBO", "NALOB", "BAOLN", "NAOLB", "BAONL", "NAOBL", "LNABO", "LNAOB", "BNALO", "BNAOL", "LNOBA", "BNLOA", "BNOLA"] j=[1,2,3,4,5].permutation.select{|a,l,b,o,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)}. map(){|a|a.zip("ALBON".chars).sort.map{|o,p|p}.join}; p j.size;p j; 17 #=> ["LAOBN", "LAONB", "BALON", "BALNO", "NALBO", "NALOB", "BAOLN", "NAOLB", "BAONL", "NAOBL", "LNABO", "LNAOB", "BNALO", "BNAOL", "LNOBA", "BNLOA", "BNOLA"] j=[1,2,3,4,5].permutation.select{|a,l,b,o,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)} . map(){|a|a.each_with_index.map{|x,o|"ALBON".chars[a.to_a.index(o+1)]}.join}; p j.size;p j; 17 #=> ["LAOBN", "LAONB", "BALON", "BALNO", "NALBO", "NALOB", "BAOLN", "NAOLB", "BAONL", "NAOBL", "LNABO", "LNAOB", "BNALO", "BNAOL", "LNOBA", "BNLOA", "BNOLA"] # ještě jedna ukázka - záměna písmen v kódu by neměla mít vliv -což potvrzuje se. první kód vrací stejný výsledek, ale druhý jinou sadu j=[1,2,3,4,5].permutation.select{|a,o,l,b,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)} . map(){|a|a.each_with_index.map{|x,o|"AobLN".chars[a.to_a.index(o+1)]}.join}; p j.size;p j; 17 #vs j=[1,2,3,4,5].permutation.select{|a,o,l,b,n |[1,4].none?(a) && l!=2 && [1,2].none?(o) && n!=3 && [2,3].none?(b)}. map(){|a|a.join.tr("12345","AolBN")}; p j.size;p j;
Offline
Ahoj, asi jsem přehlédl (nebo to tam není) v jaké programovacím jazyce je to psané.
Offline
Je to v jazyku ruby. Je to hodně funkcionální zápis ( dá se říct lambda funkce v {} a argumenty v {|a1,a2|tělo} ), ale naprosto rozumím, že se v tom někdo ztratí, třeba funkce mají nepovinné závorky , bez argumentu je zápis jednoznačný. A tu funkce přijímací jako argument blok {} je v podsatě předání argumentu , ale jeden blok lze předat v {}, takže třeba je možné [1,2,3].reduce(100){|a,b|a+b} == 106. Já bych třeba se ztratil v Lispu
Ale většina kódu je omáčka okolo, hlavní je ten select(){} co má dělat tu filtrovací podmínku a očividně dává invertovanou permutaci
obvykle používané funkce funkcionálního programování (select, map),
none?()=test, zda pole neobsahuje žádný prvek
a pomocné
tr substituce znaků
join spojení pole znaků na text
chars= rozbití řetězce na pole znaků
... kód(psaný v interaktivně) jsem lehce upravil(výpis výsledků ), aby šel rovnou spustit jako skript
Offline