Bu sayı iyi bir 2048 kombinasyonu yapar mı?


12

Esinlenerek XKCD .

Zorluk, bir sayının oyunda 2048 iyi bir kombinasyon yapıp yapmayacağını belirlemektir . Girişiniz aşağıdaki gibi bir sayı olacaktır:

8224

Ve çıkış bu sayı bu giriş için olacağını iyi 2048 combonuzu yapacak mı olacak trueyoksa yesveya 1veya pozitif sonucun göstergesi herhangi başka bir yol.

Oyunun aşina olmayanlar için, burada basit bir açıklama verilmiştir: ikisinin güçler böyle bir ızgara üzerinde düzenlenir: [2] [2]. Fayanslar herhangi bir yönde hareket ettirilebilir ve iki özdeş fayans buluşuyorsa, ikisinin bir sonraki gücü haline gelirler (böylece [2] [2]sola veya sağa taşındığında [4]). Veya oyunu burada deneyebilirsiniz .

"İyi bir 2048 kombinasyonu" ne anlama geliyor? "2048" oyunda ise tek bir sayıya birleştirilebilecek herhangi bir sayı anlamına gelir. (Sıfır, boş alan anlamına gelir ve gerekirse yok sayılabilir.) Sayıların büyük olasılıkla birden fazla basamak olabileceğini unutmayın! Ancak rakamlar gerekir değil hamle arasında değişir. Bazı örnekler / test örnekleri (iyi bir kombinasyonu belirten "İyi" ve iyi olmayan "Kötü" anlamına gelir):

  • İyi: 8224 (8224 -> 844 -> 88 -> 16)
  • İyi: 2222 (2222 -> 44 -> 8)
  • İyi: 22048 (22048 -> 448 -> 88 -> 16)
  • Kötü: 20482 (dış 2'leri birleştiremez veya 2048 ve 2'yi birleştiremezsiniz)
  • İyi: 20482048 (20482048 -> 4096)
  • Kötü: 210241024 (210241024 -> 22048, ancak şimdi [2] [2048] ve sayı hareketler arasında değişemediğinden birleştirilemiyor)
  • İyi: 2048 (zaten bir sayı)
  • Kötü: 2047 (2'nin gücü değil)
  • Kötü: 11 (oyunda 1 yok)
  • İyi: 000040000000 (sıfırlar boş alanlardır)

Çeşitli kurallar:

  • Girdi makul herhangi bir yerden olabilir, yani STDIN, işlev bağımsız değişkeni, dosya vb.
  • Çıktı ayrıca makul bir yerde olabilir, yani STDOUT, işlev dönüş değeri, dosya vb.
  • Izgara boyutunu yok sayın - 22222222yine de doğru çıkmalıdır.
  • Bu, ikisinin gücü olduğu sürece, s sayısının ne olabileceği konusunda maksimum değildir. Bu nedenle, olası sayılar 0'dan büyük iki güçtür.
  • Belirsizlik yaratan sıfırlardan endişe edenler için durum böyle değil. Örneğin, 22048ya [2] [2048]da olarak ayrıştırılabilir [2] [2] [0] [4] [8]. Birincisi çalışmıyor, ikincisi işe yarıyor, bu yüzden doğru çıktı almalı.
  • Bu , bu yüzden bayt içindeki en kısa kod kazanacak!

2
cevap sağlayan bir sunucu alabilir miyim ve sadece ondan girdi indirme cevabı yükleyebilir miyim? toplam indirme baytı olacak1
Bryan Chen

4
@Geobits 2048 zaten bir ya da dört sayı olarak belirsiz.
John Dvorak

3
Sıfır, boş bir alan anlamına gelmemelidir; 1024 yasal bir sayı mı, değil mi? Boş alanlar açık olmalı ... ve bu yüzden onlara sahip olmak, bence soruya katkıda bulunmuyor.
Tal

7
Üçüncü örneğiniz 22048çıktı almalı goodancak bu doğru değil. Sen birleştirmek olamaz 2ile 2048ve ızgara olan 4x4tüm numaralar 5 hücrelerini elde edersiniz ayrı olmalıdır eğer. yani belki kaldırmak gerekir 0? Ayrıca oyunun durduğu için 5. örneğiniz geçersiz görünüyor 2048:)
Teun Pronk

2
@undergroundmonorail Oyunda 4096 kiremit olduğunu onaylayabilirim.
Kendall Frey

Yanıtlar:


0

GolfScript, 137 karakter

[0`]1$,4*,{2\)?`}%+:W;[]\]][]\{{:A;W{A 1=\?!},{[.A~@,>\@~+\].~!{0-.,/@+\0}*;}%~}%.}do+.{~}%,{{.-1%}%.&{[{.2$={+)}*}*]{1|(}%}%}*{,1=},!!

Giriş STDIN'de verilmelidir. Çıktı kötü / iyi sayılar için 0/ 1içindir. Kodun çoğu, olası girdileri ayrıştırmak için gereklidir.

Bu daha kısa versiyon (113 karakter) gibi girişler için düzgün çalışmayan basit bir kaydırma testi gerçekleştirir 224422.

[0`]1$,4*,{2\)?`}%+:W;[]\]][]\{{:A;W{A 1=\?!},{[.A~@,>\@~+\].~!{0-.,/@+\0}*;}%~}%.}do+{W{~[.:S]/[S.+]*}/,1=},!!

Tüm test durumları çevrimiçi olarak kontrol edilebilir .


3

Python: 457422 karakter

z=range
def c(n):
 for x in z(1,12): 
  if int(n)==2**x:return 1
 return 0
def p(s):
 if s=='':return[]
 for i in z(len(s),0,-1):
  if c(s[:i])>0and p(s[i:])!=1:return [int(s[:i])]+p(s[i:])
 return 1
def r(a):
 if len(a)==1:return 1
 i,t=1,a[:1]
 while i<len(a):
  if a[i]==t[-1]:t[-1]*=2
  else:t+=[a[i]]
  i+=1
 if len(t)==len(a):return 0
 return r(t) 
def f(s):
 if p(s)==1or r(p(s))==0:print('bad')
 else:print('good')

F (s) işlevi bir dizi rakam alır ve buna göre 'iyi' veya 'kötü' çıktılar verir. 0'ı boşluk olarak kullanmamayı seçtim çünkü oyunda boşluklar anlamsız ve dizeleri ayrıştırırken belirsizlikler yaratıyorlar (22048 iyi mi kötü mü?). Bu yalnızca 2048'e kadar olan sayıları kullanır, ancak bu karakter eklenmeden değiştirilebilir. 10 karakter ya da öylesine pahasına ben de sayıları birleştirmek tüm adımları yazdırabilirsiniz. Ve bu kod henüz yeterince golf olmadığını fark; endişelenme, düzenlemeler geliyor.


Girintiye bazı karakterleri kaydetmek için boşluk ve sekme numarasını kullanabilirsiniz. SO markdown olsa onu kıracak.
gcq

Bence Python 3.x üzerinde çalışmıyor. Yapabileceğim çok şey var, ama bu Haskell cevabı ile rekabet edebileceğimden emin değilim :)
Tal

Evet, bunu unuttum.
gcq

2

Haskell: 285254253 237 230227

kullanımı - sadece ghci'ye yükleyin ve dizeyi h'ye geçirin.

*Main> h "210241024"
False
*Main> h (replicate 1024 '2') -- very long string
True
*Main> h (replicate 1023 '2') -- odd one out
False

Kod:

t=i 0
i n=mod n 2<1&&(n<3||i(div n 2))
a%[]|i a=[[a]]|t=[];a%(b:c)=[a:d|d<-b%c,i a]++(a*10+b)%c
c(0:a)=c a;c(a:b:d)|a==b=(a+a):c d|t=a:c(b:d);c a=a
l a=c a/=a&&(g.c)a
g[a]=t;g a=l a||(l.reverse)a
h b=any g$0%(map(read.(:[]))b)

Yorum: ibir sayının 2 gücü olup olmadığını kontrol etmek, bu biraz twiddling dilleri tarafından aşılacak. %2 veya 0 güç listesi olan tüm ayrıştırmaları özyinelemeli olarak üretir c. lfayansların katlanabilir sola veya iyi olup olmadığını tekrar tekrar test eder. gkaroların sola veya sağa katlanabilir olup olmadığını test eder. Karoların üzerindeki sayılar için bir sınır yoktur - örneğin h ((show (2^200))++(show (2^200)))"1606938044258990275541962092341162602522202993782792835301376" olarak işaretlenmiş 2 karo için doğru döndürür.

Doğru "88222288888" sağa daraltmadı bir hata düzeltmek için düzenlenmiş, ancak aynı zamanda daha fazla golf fırsatları bulundu.


2

Perl, 175-336 bayt

while(<>){chomp;$n="nothing";$\=("."x(1+/^[2048]+$/+/^((\d+)0*\2)+$/+((sprintf"%b",
$_)!~/1.*1/)))."\n";($o=$\)=~y/.\n/oh/;print$o;$m=length;for$i(1..$m){$a=$_;$r=
qr((\d*[2468])0*\2)0*/;($b=substr$a,0,$i,"")=~s/$r/$2+$2/ge;@n=$"="$b$a";push@n,$"while$"
=~s/$r/$2+$2/ge;($"%2&&next)||($">>=1)while$">1;$n="nice";(print)for@n;last}print$n}

Sadece gerekli bilgileri sağlam tutmak:

$_=shift;$m=length;for$i(1..$m){$a=$_;$r=qr/((\d*[2468])0*\2)0*/;($b=substr$a,0,$i,"")=~
s/$r/$2*2/ge;$"="$b$a";1while$"=~s/$r/$2*2/ge;($"%2&&next)||($">>=1)while$">1;exit}die;

1

ooh .. 1 .. güzel ..

2

oooh ... 2 ... güzel ...

22

oooh ... 22 ... 4 ... güzel ...

42

ooh .. hiçbir şey ..

422

ooh .. 422 .. 44 .. 8 .. güzel ..

322

ah. hiçbir şey değil.

336

ah. hiçbir şey değil.

4224

ooh .. hiçbir şey ..

4228

ooh .. 4228 .. 448 .. 88 .. 16 .. güzel ..

16022481602248

ooh .. 1604481602248 .. 16088160448 .. 1601616088 .. 3216016 .. 3232 .. 64 .. güzel ..

[ 64 ve açgözlü eşleme başa çıkamaz ... ama bunlar bazı kötü çözülebilir belirsizliklere 256 kurşun güzel bayt sayar. ]

2048

oooh ... 2048 ... güzel ...


1

Delphi 572582 karakter

Düzenlenmiş kod, limit 2 ^ 30 olarak ayarlanmıştır, böylece Delphi'deki MaxInt değerini aşmaz.

golfed

uses SysUtils,Classes;var t,j,c:integer;s,n:string;L:TStringList;function p(x:string):boolean;var r,i:int64;begin if x='0'then exit(1>0);i:=2;r:=StrToInt(x);while i<r do i:=i*2;p:=i=r;end;begin read(s);t:=0;L:=TStringList.Create;j:=1;while j<=Length(s)do begin for c:=9downto 1do begin n:=copy(s,j,c);if p(n)then break;end;if n>'0'then L.Add(n);j:=j+Length(n);end;for j:=0to L.Count-1do t:=t+StrToInt(L[j]);j:=0;repeat if j=L.Count-1then break;if L[j]=L[j+1]then begin L[j]:=IntToStr(StrToInt(L[j])*2);L.Delete(j+1);j:=0;end else inc(j);until L.Count=1;write(strtoint(L[0])=t);end.

Ungolfed

uses
  SysUtils,
  Classes;

var
  t,j,c:integer;
  s,n:string;
  L:TStringList;
  function p(x:string):boolean;
  var
    r,i:int64;
  begin
    if x='0'then exit(1>0);
    i:=2;r:=StrToInt(x);
    while i<r do
      i:=i*2;
    p:=i=r;
  end;
begin
    read(s);
    t:=0;L:=TStringList.Create;
    j:=1;
    while j<=Length(s)do
    begin
      for c:=9downto 1do
      begin
        n:=copy(s,j,c);
        if p(n)then break;
      end;
      if n>'0'then L.Add(n);
      j:=j+Length(n);
    end;
    for j:=0to L.Count-1do
      t:=t+StrToInt(L[j]);
    j:=0;
    repeat
      if j=L.Count-1then break;
      if L[j]=L[j+1]then
      begin
        L[j]:=IntToStr(StrToInt(L[j])*2);
        L.Delete(j+1);j:=0
      end
      else
        inc(j);
    until L.Count=1;
    write(strtoint(L[0])=t);
end.

DÜZENLE

Bu yüzden merak ettim ve bu kombinasyonlardan kaç tanesinin buluta uyduğunu ve bir test çalıştırdığını merak ettim.

Meraklı olanlar için de bir test yapın;)

Ama sonuç burada:
20736 combinations were tested and 1166 were great combinations

Ben (markaları sağ anlamda?) 3 veya daha fazla sıfır ile kombinasyonlar atlandı söylemeliyim
Kombinasyonlar kombinasyonları anlamına neredeyse benzersiz olan 2248, 8224, 8422ve 4228tüm büyük kombinasyonu olarak sayıldı.


1

Mathematica - 218 bayt

f=MemberQ[DeleteCases[Map[FromDigits,l~Internal`PartitionRagged~#&/@Join@@Permutations/@IntegerPartitions@Length[l=IntegerDigits@#],{2}],{___,x_,___}/;!IntegerQ[2~Log~x]||x<2]//.{a___,x_,x_,b___}:>{a,2x,b},{_Integer}]&

Ungolfed sürümü:

f[n_] := MemberQ[
  DeleteCases[
      Map[
        FromDigits, 
        Internal`PartitionRagged[l, #] & /@ 
          Join @@ Permutations /@ IntegerPartitions[Length[l = IntegerDigits[n]]], 
        {2}
      ],
      {___, x_, ___} /; x < 2 || ! IntegerQ[2~Log~x]
    ]
  ] //. {a___, x_, x_, b___} :> {a, 2 x, b}, 
  {_Integer}
]

Internal\PartitionRagged` sihirli alınır bu soruya .

Bu çözüm, rastgele ızgara boyutlarını ve keyfi olarak büyük sayıları ele alır.

İşte ise 195 bayt sadece 4 çinileri (şimdiye kadar yukarıya gerçek oyun gibi çalışır versiyonu f[22222222]olan False):

f=MemberQ[(d=DeleteCases)[d[ReplaceList[IntegerDigits@#,{a__,b___,c___,d___}:>FromDigits/@{{a},{b},{c},{d}}],0,2],{___,x_,___}/;!IntegerQ[2~Log~x]||x<2]//.{a___,x_,x_,b___}:>{a,2x,b},{_Integer}]&

nerede değiştirdim

Map[
  FromDigits, 
  Internal`PartitionRagged[l, #] & /@ 
    Apply[
      Join, 
      Permutations /@ IntegerPartitions[Length[l = IntegerDigits@#]]
    ], 
  {2}
]

ile

ReplaceList[
  IntegerDigits[n], 
  {a__, b___, c___, d___} :> FromDigits /@ {{a}, {b}, {c}, {d}}
]

Bu kodumun yaptığı aynı hataya sahip olup olmadığını merak ediyorum - en DeleteCasessoldaki çiftleri kaldırıyor gibi görünüyor, bu yüzden f[88222288888]başarısız olur mu?
bazzargh

@bazzargh hayır, DeleteCasessadece ikisinin gücü olmayan sıfırları ve sayıları kaldırın. Çiftlerin gerçek çökmesi, //. {a___, x_, x_, b___} :> {a, 2 x, b}bu sayı ve tersi için çalışan kural tarafından yapılır . Aslında Mathematica'nın bu değiştirmeleri uyguladığı sıradan tamamen emin değilim, ama işe yarıyor.
Martin Ender

1

Haskell - 260263

import Data.Bits
p[x]=[[[x]]]
p(x:s)=do r@(h:t)<-p s;[[x]:r,(x:h):t]
q=filter(and.map(\n->(n::Integer)/=1&&n.&.(-n)==n)).map(filter(/=0)).map(map read).p
c(x:y:s)
 |x==y=2*x:c s
 |True=x:(c$y:s)
c x=x
r[x]=True
r l=c l/=l&&(r(c l)||r(c$reverse l))
f=or.map r.q

ffonksiyonudur. Örnekler:

> f"22228"
True
> f"20482044"
False

Küçük bir açıklama:
pbir listeyi bölmenin tüm yollarını döndürür.
qsadece 2 güçten oluşanları filtreler (1 hariç ancak 0 dahil).
cbir dizeyi daraltmaya çalışır.
ryalnızca 1 öğe kalmayıncaya veya dize çakışmayana kadar sağ ve sol daralmayı yineler.


Güzel. Yine de bir hata var c, "222244442222" deneyin - bu doğru döner, ama bu oyunda daraltılamaz. İle recurse gerekir (2*x):c s.
bazzargh

@bazzargh fixed
mniip
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.