Aristoteles'in Sayı Problemini Çözme


21

Aristoteles'in sayı bulmacası, 19 hücrenin her birini altıgen bir ızgarada 1 ila 19 arasında benzersiz bir tamsayı ile doldurma zorluğudur, öyle ki her eksen boyunca toplam 38'dir.

Oyun tahtasının şöyle görünmesini hayal edebilirsiniz:

aristotel ızgarası

Ve bulmaca, özünde, aşağıdaki on beşlik denklem grubunun çözümü:

((a + b + c) == 38 && (d + e + f + g) == 38 && (h + i + j + k + l) == 
   38 && (m + n + o + p) == 38 && (q + r + s) == 38 && (a + d + h) == 
   38 && (b + e + i + m) == 38 && (c + f + j + n + q) == 
   38 && (g + k + o + r) == 38 && (l + p + s) == 38 && (c + g + l) == 
   38 && (b + f + k + p) == 38 && (a + e + j + o + s) == 
   38 && (d + i + n + r) == 38 && (h + m + q) == 38)

Her değişkenin kümedeki benzersiz bir sayı olduğu yer {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}.

Çok sayıda olası çözüm vardır ve 19!olası tamsayı kombinasyonları vardır, bu yüzden saf kaba kuvvet pratik olmaz.

Kurallar:

  1. Cevabı kodlama ya da cevabı başka yerde arama; kodun kendi başına bulmalı
  2. Hız önemli değil, ancak sonuçlarınızı göstermeniz gerekiyor, bu nedenle çalıştırılması 1000 yıl süren kod size yardımcı olmaz
  3. Tüm cevapları bul
  4. Döndürme altında aynı olan cevapları aynı olarak kabul edin
  5. Sonuçları etkileyici bir bal peteğinde çıkarırsanız toplam bayt sayınızın% 5'ini düşürün
  6. En az bayt kazanır

Harika bir soru, bunun için bir çözüm için sabırsızlanıyoruz.
ProgramcıDan

Döndürülmüş cevapları benzersiz olarak mı düşünüyorsunuz? Örneğin, a, b, c = 1, 18, 19'un belirli bir çözümü endekslediğini varsayalım, c, g, l = 1, 18, 19 olarak ayarladıysak ve diğer tüm değerler eşleşecek şekilde "döndürülmüşse", bunun benzersiz olduğunu düşünüyor musunuz? çözüm?
ProgramcıDan

@ProgrammerDan Döndürülen cevaplar aynıdır. Netleştireceğim.
Michael Stern

1
Bir altıgen, sadece dönmelerden daha fazla simetriye sahiptir. Bir rotasyon ve yansıma kombinasyonu altında özdeş olan cevaplara ne demeli?
Peter Taylor

Kendini organize eden haritaları kullanarak buna bir çözüm görmekle ilgileniyorum.
Ant P

Yanıtlar:


3

Haskell 295 289

import Data.List
t=38
y a b=[max(19-b)(a+1)..19]
w=y 0 t
x=filter((==w).sort)$[[a,b,c,d,e,f,g,h,i,t-a-e-o-s,k,l,m,t-d-i-r,o,p,q,r,s]|a<-[1..14],c<-y a a,l<-y a c,s<-y a l,q<-y a s,h<-y c q,e<-w,let{f=t-g-e-d;i=t-b-e-m;o=t-r-k-g;k=t-p-f-b;b=t-a-c;g=t-l-c;p=t-l-s;r=t-q-s;m=t-q-h;d=t-a-h}]

Bir başka benzer cevap, ara hexes elde etmek için aritmetik kullanarak. Diğer çözümlerden farklı olarak,> 0 olan bu toplamları test etmiyorum, sıralanan altıgenlerin [1..19] aralığına eşit olduğunu test etmek yeterli. a, c ve h, sadece benzersiz döndürülmüş / yansıtılmış çözeltilere izin verecek şekilde sınırlandırılmıştır. Çözüm birkaç saniye sonra ortaya çıkıyor, daha sonra bir dakika kadar beklemek yok.

Ghci içinde kullanımı:

ghci> x
[[3,19,16,17,7,2,12,18,1,5,4,10,11,6,8,13,9,14,15]]

Birkaç karakter tıraş için düzenlendi. 'y 0 t' üretir [1..19].


1
Aslında C cevabımda aynı şeyi yapıyorum :) kahrolası Haskell'in bu iş için mükemmel bir araç olduğunu nasıl göremedim: P +1
Niklas B.

x>0Çekinizi özlüyorum , çünkü bir diziyi artırmak yerine negatifleri içeren listeyi sıralarım. Öte yandan, y a bHaskell'in performans göstermesi için aralıkları sınırlandırmam gerekiyor ( ki bu da bana birkaç kuruşa mal oluyor). Ama aynı şekilde çalışarak beni yenecek şekilde yerleşik olan başka bir dil olmalı (sana bakarken, Mathematica).
bazzargh

Evet, C’de sıralama ne yazık ki Haskell’de olduğu kadar kolay değil. Mathematica'daki problem derlenmemiş olması ve bu yüzden de çok yavaş olması :(
Niklas B.

Bunları her zaman Haskell'de pratik yapmak için yapıyorum, başka bir dil daha iyi olsa bile.
bazzargh

Aslında Haskell'i bir yan iş olarak programlıyorum, bu yüzden burada kullanmak için bile başıma gelmediğine inanıyorum: D Gerçek / saf olmayan dünyada bile - gerçekten harika bir dil
Niklas B.

10

Java (1517 - 75.85) = 1441.15 (1429 - 71.45) = 1357.55 (1325 - 66.25) = 1258.75

Bu komikti.

Hoş bir bal peteği içinde yansıtma ve döndürme ile tüm benzersiz çözümleri yazdırır (% 5 azalma)

Çalışma Zamanı: 4 yaşındaki dizüstü bilgisayarımda ~ 0.122s (122 milisaniye).

Golf kodu ( düzenleme farkına varmadan aptalca tekrarladığımı fark ettim, maksimum golf için onları tek bir baskıya indirgedim) ( yeni düzenleme Fonksiyonları daha küçük fonksiyonlara, bazı diğer mikro optimizasyonlara ayarlamak için yapılan indirgenmiş çağrılar):

import java.util.*;class A{boolean c(Set<Integer>u,int z){return!u.contains(z);}Set<Integer>b(Set<Integer>c,int...v){Set<Integer>q=new HashSet<Integer>(c);for(int x:v)q.add(x);return q;}void w(){Set<Integer>U,t,u,v,w,y,z;int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,X,Z;X=20;Z=38;for(a=1;a<X;a++)for(b=1;b<X;b++)if(b!=a)for(c=1;c<X;c++)if(c!=a&&c!=b&&a+b+c==Z){U=b(new HashSet<Integer>(),a,b,c);for(d=1;d<X;d++)if(c(U,d))for(h=1;h<X;h++)if(h!=d&&c(U,h)&&a+d+h==Z){t=b(U,a,b,c,d,h);for(m=1;m<X;m++)if(c(t,m))for(q=1;q<X;q++)if(q!=m&&c(t,q)&&h+m+q==Z){u=b(t,m,q);for(r=1;r<X;r++)if(c(u,r))for(s=1;s<X;s++)if(s!=r&&c(u,s)&&q+r+s==Z){v=b(u,r,s);for(p=1;p<X;p++)if(c(v,p))for(l=1;l<X;l++)if(l!=p&&c(v,l)&&s+p+l==Z){w=b(v,p,l);for(g=1;g<X;g++)if(c(w,g)&&l+g+c==Z)for(e=1;e<X;e++)if(e!=g&&c(w,e))for(f=1;f<X;f++)if(f!=e&&f!=g&&c(w,f)&&d+e+f+g==Z){y=b(w,g,e,f);for(i=1;i<X;i++)if(c(y,i))for(n=1;n<X;n++)if(n!=i&&c(y,n)&&d+i+n+r==Z&&b+e+i+m==Z){z=b(y,i,n);for(o=1;o<X;o++)if(c(z,o))for(k=1;k<X;k++)if(k!=o&&c(z,k)&&m+n+o+p==Z&&r+o+k+g==Z&&b+f+k+p==Z)for(j=1;j<X;j++)if(c(z,j)&&j!=o&&j!=k&&a+e+j+o+s==Z&&c+f+j+n+q==Z&&h+i+j+k+l==Z){System.out.printf("%6d%4d%4d\n\n%4d%4d%4d%4d\n\n%2d%4d%4d%4d%4d\n\n%4d%4d%4d%4d\n\n%6d%4d%4d\n\n",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s);return;}}}}}}}}}public static void main(String[]a){(new A()).w();}}

Kaba kuvvet geçerliliğini yitirmiştir, ancak yalnızca çok küçük bir çözüm kümesinin var olduğu gerçeğinin akıllıca kullanılması, yinelemeye dayalı bir cevaba yol açmıştır; yinelemenin her döngüsünde sadece "atanmamış" tamsayıları dikkate aldım. Java'nın HashSet'ini daha önce kullanılmış olan numaraların O (1) aramalarını elde etmek için kullanıyorum. Son olarak, tam olarak 12 çözüm var, ancak hem rotasyonu hem de aynayı düşürdüğünüzde, bu tek bir benzersiz çözüme indirgeniyor, bu yüzden ilk çözüme rastlandığında, onu yazdırıyorum ve sonlandırıyorum. Benim göz atın github en az golfed kodu Bu çözümü yaklaşıyorum nasıl içine daha net bir görüş biraz.

Keyfini çıkarın!


Eh, spoilerinizde uzanıyorsunuz, daha farklı çözümler var, bu yüzden cevabınız geçersiz.
ST3

Güçlü iddia, kanıtlamak için kendi cevabını vererek destekleyebilir misin? Spoyumdaki kasıtlı yalanların kesinlikle farkında değilim.
ProgramcıDan

bu yüzden ilk çözüme ulaşıldığında, onu yazdırırım ve kural no. 3 tüm cevapları bulmayı söyler. OP'nin dediği gibi 19, gerçekten 19 olup olmadığından emin değilim, ama daha önce benzer bir işle karşılaştım, o yüzden bir tanesinden daha fazla olduğunu biliyorum.
ST3

Tüm spoylerimi okumalısın . 12 çözüm buldum. O zaman soruyla ilgili tüm yorumları okumanız gerekir . OP, eşit wrt rotasyona eşit cevapların eşdeğer olduğunu ve atlanması gerektiğini söylüyor. Başka bir kişi cevapların eşit wrt yansıtma atlanıp atlanmayacağını sordu. OP'nin bu sorguya cevap vermemesi gerekmesine rağmen, hem tarih hem de tüm diğer çözümler cevabın "evet" olduğunu varsayar. Dolayısıyla benim çözümüm tamamen tamamlandı, tam olarak doğru ve burada "yalan" yok. Ancak, 12 çözümün tümünü de görmek istiyorsanız, return;ifadeyi kaldırın .
ProgramcıDan

Son olarak, bu kod golf. İsteğe bağlı bir return;ifade eklemeyi düşünmek kod uzunluğumu 7 artırıyor, doğru cevap birbirinin basitçe döndürülmüş / yansıtılmış sürümlerinin hepsini de içeren 12 çözümü içeriyorsa, bunu eklemek benim için delice gelecektir. Her ne kadar delilik göz ardı edilemese de, bu durumda, ilavesi return;kasıtlı olarak yapıldı ve tarif ettiğim gibi, suçlamalardan önce incelemeye dikkat etmeniz gereken tam soru ve yorumlar iletişim kutusunu temel alarak . Teşekkürler!
ProgramcıDan

8

C, 366 bayt ( C ++ 541 450 )

#define R(i)for(int i=19;i;--i)
#define X(x)if(x>0&&!V[x]++)
#define K(X)X(a)X(b)X(c)X(d)X(e)X(f)X(g)X(h)X(i)X(j)X(k)X(l)X(m)X(n)X(o)X(p)X(q)X(r)X(s)
Q(x){printf("%d ",x);}
T=38,V[99];main(){R(h)R(c)R(s)R(a)R(l)R(q)R(e){int d=T-a-h,b=T-a-c,g=T-c-l,p=T-l-s,r=T-q-s,m=T-h-q,f=T-g-e-d,i=T-b-e-m,n=T-d-i-r,o=T-p-n-m,k=T-g-o-r,j=T-h-i-k-l;R(C)V[C]=0;K(X)K(+Q),exit(0);}}

İle derleyin gcc -std=c99 -O3.

Tüm benzersiz çözümleri modulo döndürme ve yansıtma, a b c d ...her satırda bir biçiminde yazdırır .

Çalışma zamanı: Bilgisayarımda 0.8 saniye.

Maksimum budama kabiliyeti için hücreleri h -> c -> s -> a -> l -> q -> e sıralarına göre sıralarız. Aslında yukarıdaki sürüm sadece bu değişkenler için her 20 ^ 7 ödevini dener. Sonra diğer tüm hücreleri de hesaplayabiliriz. Tek bir benzersiz çözüm modülo döndürme / yansıtma vardır. Yaşlı bir az C ++ sürümü (nedeniyle budama kadar) golfed ve ~ 20 kat daha hızlı bulunabilir Github


Buradaki büyük ölçüde aritmetik yaklaşımı seviyorum. Bravo! +1
ProgramcıDan

1

Matlab: 333 320 karakter

Bu, özyineleme kullanmayan oldukça aptal bir kaba kuvvet yaklaşımıdır. Sonunda zbasılmış olan kısmi çözümler oluşturur . Her sütun bir çözümdür; elemanlar yukarıdan aşağıya doğru listelenmiştir. Çalışma süresi 1-2 saattir.

z=[];
a='abc adh hmq qrs spl lgc defg beim mnop dinr rokg pkfb hijkl aejos cfjnq';while a[k,a]=strtok(a);n=length(k);x=nchoosek(1:19,n)';s=[];for t=x(:,sum(x)==38)s=[s,perms(t)'];end
m=0.*s;m(19,:)=0;m(k(1:n)-96,:)=s(1:n,:);y=[];for p=m for w=z m=[];l=w.*p~=0;if p(l)==w(l) y(:,end+1)=w+p.*(~l);end
end
end
z=[m,y];end
z

Matlab içinden koşmak:

>> aristotle;
>> z(:,1)

ans =

    9
   11
   18
   14
    6
    1
   17
   15
    8
    5
    7
    3
   13
    4
    2
   19
   10
   12
   16
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.