Matematické Fórum

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

#1 24. 06. 2024 19:48 — Editoval <h1>dydy</h1> (25. 06. 2024 19:49)

<h1>dydy</h1>
Příspěvky: 161
Reputace:   
 

kód mi vrací inverzní permutaci

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)

Code:

#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

 

#2 25. 06. 2024 10:28

check_drummer
Příspěvky: 4782
Reputace:   105 
 

Re: kód mi vrací inverzní permutaci

Ahoj, asi jsem přehlédl (nebo to tam není) v jaké programovacím jazyce je to psané.


"Máte úhel beta." "No to nemám."

Offline

 

#3 25. 06. 2024 13:37 — Editoval <h1>dydy</h1> (25. 06. 2024 19:50)

<h1>dydy</h1>
Příspěvky: 161
Reputace:   
 

Re: kód mi vrací inverzní permutaci

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

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson