Golfçü Macerası - Bölüm 1: Vazo


13

Golfçü Macerası

Bu ilk meydan okuma! Daha sonra, bir önceki zorluktan veri gerektirecek daha fazla zorluk olacak :)

Bölüm 1: Vazo

Bir dakika düşünelim .. Siz güçlü bir Tanrı'sınız, güçleriniz sınırsızdır, ancak bir şey gerektirir: Ruhlar. Her ruh burada bir bayt ile temsil edilir, kullandığınız her bayt bir ruhu feda eder. Dolayısıyla amaç, en az miktarda ruhu feda ederken en fazla insanı kurtarmaktır.

İlk zorluğunuz küçük bir köyü kurtarmak, şeytan onun meydan okumasını çözerseniz tüm köyü yok etmemek istiyor.

Meydan okuma :

Tam olarak 10 şey içerebilen dikey bir vazo var (Hava dahil). Eğer o vazoya bir şey koyarsanız, yerçekimi o şeyi dibe düşürür. Vazo zaten doluysa (ve "havayla dolu" olarak kabul ederseniz her zaman doluysa), giriş vazonun üstündeki öğenin yerini alacaktır.

İzin verilen şeyler kümesi:

  • Hava 0 /
  • Bir kaya 1 / -
  • Bir yaprak 2 / ~
  • Bir bomba 3 / x

"Bomba" nın üstünde bir kaya ya da yaprak varsa, patlayacak ve tepesindeki şeyi yok edecektir.

Girdi, her turda vazoya koyacağınız şeylerin listesidir.

Örnek: 11231: 2 taş, sonra bir yaprak, sonra bir bomba ve son olarak son bir kaya koyacaksınız.

Vazo statik olduğunda, aşağıdaki kuralla saymaya başlayabilirsiniz:

  • Rock akümülatöre 1 birim ekler
  • Yaprak akümülatörü 2 ile çarpar
  • Akümülatör bomba azaltmak 1
  • Hava hiçbir şey yapmaz

(Sayımın vazonun üstünden başlamanız gerekir)

İşte girdi olarak "11231" kullanarak elde ettiğimiz simülasyon:

|-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |  | |  | |
| |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |  | |
| |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |  | |
| |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |  | |
| |  | |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |  | |
| |  | |  | |  | |  | |  |-|  |-|  |~|  |x|  |-|  | |
| |  | |  | |  | |  | |  | |  |-|  |-|  |~|  |x|  | |
| |  | |  | |  | |  | |  | |  | |  |-|  |-|  |~|  |~|
| |  | |  | |  | |  | |  | |  | |  | |  |-|  |-|  |-|
| |  | |  | |  | |  | |  | |  | |  | |  | |  |-|  |-|

Ve çıktı 2 (olarak hesaplanır ((0 x 2) + 1) + 1) Vazo tüm durumlarını yazdırmaya gerek yok!

Temel program (Python3)

Nasıl çalıştığını anlamak için yürütebilirsiniz.

def printVase(vase):
  for i in vase:
    if i == 1:
      print("|-|")
    elif i == 2:
      print("|~|")
    elif i == 3:
      print("|x|")
    else:
      print("| |")

def updateVase(vase):
  changed = False
  for i in range(len(vase), -1, -1):
    if i < len(vase) - 1:
      if vase[i+1] == 3 and vase[i] in [1,2]:
        vase[i], vase[i+1] = 0, 0
        changed = True
      if not vase[i+1] and vase[i] in [1, 2, 3]:
        vase[i], vase[i+1] = vase[i+1], vase[i]
        changed = True
  return changed

userInput = input("Vase : ")
vase = [0 for i in range(0, 10)]
oldVase = vase
while updateVase(vase) or userInput != "":
  if userInput != "":
    vase[0] = int(userInput[0])
  userInput = userInput[1::]
  printVase(vase)
  input()

accumulator = 0
for i in vase:
  if i == 1:
    accumulator += 1
  if i == 2:
    accumulator *= 2
  if i == 3:
    accumulator -= 1
print(accumulator)

Golf edilmiş sürüm (Python3, Vazo Göstergesi yok): 360 bayt = 360 puan

def u(v):
  c=0
  for i in range(len(v),-1,-1):
    if i<len(v)-1:
      if v[i+1]==3 and v[i]in[1,2]:v[i],v[i+1],c=0,0,1
      if not v[i+1]and v[i]in[1,2,3]:v[i],v[i+1],c=v[i+1],v[i],1
  return c
l,v=input(),[0 for i in range(0, 10)]
while u(v)or l!="":
  if l!="":v[0],l=int(l[0]),l[1::]
a=0
for i in v:
  if i==1:a+=1
  if i==2:a*=2
  if i==3:a-=1
print(a)

Programınızın doğru çalışıp çalışmadığını test etmek isterseniz, bu girişi test edebilirsiniz: 12122111131

Doğru cevap 43 :) (Teşekkürler Emigna)

Şimdi puan için:

  • (x) şu noktalara işaret eder: x, programınızı yazmak için gereken bayt miktarıdır. Bir sonraki meydan okuma gönderildikten sonra cevaplarsanız, bu meydan okuma için puanlar toplam puanınıza eklenmez.

Amaç, tüm meydan okuma boyunca minimum puan tutmaktır :) Meydan okuma kısmından birini atlarsanız, atlanan kısım için varsayılan olarak (wx + 1) puanınız olur (burada wx en kötü puandır) bu meydan okuma için).

Bir sonraki zorluk için gerekli veriler:

Giriş = 10100000200310310113030200221013111213110130332101

Güncel Şampiyon: Emigna

Herkese iyi şanslar !


2
"Tam olarak 10 şey içerebilir" ne? "Hava" bir şey olarak sayılır mı? Girdinin vazoda sadece 10 şey olacak şekilde garanti ediliyor mu (referans uygulamasında kullanıldığını görmüyorum)? Ayrıca bir sonraki meydan okuma için veri üreten girdinin 10'dan fazla şeye sahip olduğu görülüyor (hava hiçbir şey gibi olmasa ve bombalar bir sonraki şeyi havaya uçursa bile 14 şey olacak).
Jonathan Allan

1
Bir girdi , golf algoritmanızda 333bir vazo [0, 0, 0, 0, 0, 0, 0, 3, 3, 3]oluşturur ve bu nedenle bir puan verir -3, ancak şartnamenize göre [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]bir puan olmamalı ve sonra bir puan olmamalıdır -1?
Laikoni

2
@Laikoni Bir bomba başka bir bombanın üstündeyken bombaların patlamayacağını belirtmeyi unuttum, teşekkürler!
Sygmei

1
10100000200310310113030200221013111213110130332101 için çıktı 22 gibi görünüyor, değil mi?
Outgolfer Erik

2
12122111131 gibi zor bir test senaryosu eklemek iyi bir fikir olabilir.
Emigna

Yanıtlar:


5

Python 2 - 208 191 185180172164 156 bayt

t=filter(bool,map(int,input()))
i=a=0
n=len(t)
while 0<n-1>i<11:
 if(t[i]>=3>t[i+1]):del t[i:i+2];i,n=0,n-2
 i+=1
for x in t[9::-1]:a+=a+x%2*(2-x-a)
print a

Arıza, havayı kaldırır ve yığın üzerinde ise bombalar sayar.

EDIT: Bir bayt kaydetmek için Python 2 takas, ama şimdi giriş '3312123' gibi parantez koymak gerekir

EDIT2: Ayrıca akümülatör sayısıyla gurur duyuyorum

EDIT3: Tüm önerileriniz için teşekkürler, bu kadar düşük olabileceğimi asla düşünmezdim


Güzel ilk cevap! Python ile de düşünüyordum ama bugün çok az zaman geçirdim. Benim yaklaşımımı yine de yeneceğini düşün.
ElPedro

Nazik yorum için teşekkürler :) İlk kez bir kod golf yapıyorum ve oldukça eğlenceli olduğunu söylemeliyim.
Pâris Douady

Kullanın t[:10][::-1]yerine reverse()belki bir braket kaydetmek için Python 2 kullanmak da 4 bayt tasarruf etmek ve print? Benim için kurtarılmış 5 ruh daha geliyor :)
ElPedro

Benim için Python2 yok çünkü çalışması için str () atmak zorunda kalacaktım, 5 ruh daha öldürmek. [:: - 1] güzel yakalama
Pâris Douady

btw, soruda girdinin 'tırnak içine alınabileceğini' söyleyen bir şey görmedim. Sadece "Girdi, şeylerin listesidir" der. Python 2'de çalışıyor :)
ElPedro



3

Piton 2, 150 146 bayt

v=[]
s=0
for c in input():
 v=v[:9]
 if'0'==c:1
 elif 3 in v[-1:]and c in'21':v=v[:-1]
 else:v+=[int(c)]
for x in v[::-1]:s+=s+x%2*(2-x-s)
print s

Puan formülü ve 4 byte tasarruf için Pâris Douady'a teşekkürler.


Noktanın sayılması için formülümü aldın mı? Her iki şekilde de güzel bir çözüm, beni dövüyorsun ve çok daha temiz. Ayrıca for c in input()doğrudan yaparak bazı baytlar kaydedebilirsiniz
Pâris Douady

2

JavaScript, 267 264 249 ruhlar feda

r='replace'
f=t=>{t=t[r](/0/g,'');while(/3[12]/.test(t.substring(0,10)))t=t[r](/3[12]/,'');
a=t.length-1;x=(t.substring(0,9)+(a>8?t[a]:'')).split('').reverse().join('');
c='c=0'+x[r](/1/g,'+1')[r](/2/g,';c*=2;c=c')[r](/3/g,'-1');eval(c);return c}

Önceki sürüm daha büyük girişler için yanlış olduğu için düzenlenmiş sürüm. string.prototype.replace()Bir dizi erişimli işlev çağrısı yaparak biraz daha golf . Açıklama:

f=t=>{                                  Function declaration, input t
t=t.replace(/0/g,'');                   Remove air
while(/3[12]/.test(t.substring(0,10)))  Look for bombs; not double bombs, and only in the first 10 chars
    t=t.replace(/3[12]/,'');            Detonate bombs. If this makes a new bomb fall into the vase, or
                                        a double bomb is now a single bomb, it'll detonate that bomb too.
x=(t.substring(0,9)+                    Fill the vase, take the first 9 items
    (t.length>9?t[t.length-1]:''))      If we have more than 9 items, then add the last one
    .split('').reverse().join('');      Flip the instruction string.
c='c=0'+x.replace(/1/g,'+1')            Replace each item with the proper instruction to the ACC
         .replace(/2/g,';c*=2;c=c')
         .replace(/3/g,'-1');
eval(c);return c}                       Eval to get the value of ACC and return it.

f('11231');döner 2. Çevrimiçi deneyin


10100000200310310113030200221013111213110130332101 iyi sonuç vermiyor :) Yine de çok yakınsın :)
Sygmei

@Sygmei Biliyorum ve boktan hata ayıkladım, ama nedenini bulamıyorum. Eğer Can bana sohbet görüyor musunuz?
steenbergh

1

Haskell, 221 202 181 177 166 ruhlar bayt

g(0:r)=r++[0]
g(3:x:r)|0<x,x<3=0:0:g r|1<3=3:g(x:r)
g(x:r)=x:g r
g r=r
v%(x:r)=g(init v++[x])%r
v%[]|v==g v=foldr([id,(+)1,(*)2,(-)1]!!)0v|1<3=g v%[]
(([0..9]>>[0])%)

İdeone üzerinde deneyin . Öğeleri tamsayı listesi olarak alır.

Kullanımı:

*Prelude> (([0..9]>>[0])%) [1,2,1,2,2,1,1,1,1,3,1]
43

(Düzenle: Eski) Açıklama:

g [] = []                             -- g simulates gravity in the vase
g ('0':r) = r ++ "0"                  -- the first 0 from the bottom is removed
g ('3':x:r) | elem x "12" = "00"++g r -- if a 1 or 2 is on a bomb, explode 
            | True = '3' : g(x:r)     -- else continue
g (x:r) = x : g r                     -- no air and no bomb, so check next item

c x = [id,(+)1,(*)2,(-)1]!!(read[x])  -- map 0, 1, 2, 3 to their score functions

f v w (x:r) =                         -- v is the current vase state, w the previous one
               init v++[x]            -- replace last vase element with input
             g(init v++[x])           -- simulate one gravity step
           f(g(init v++[x]))v r       -- repeat, w becomes v
f v w[] | v==w =                      -- if the input is empty and vase reached a fixpoint
                 foldr c 0 v          -- then compute score 
        | True = f (g v) v []         -- else simulate another gravity step


vase input = f "0000000000" "" input  -- call f with empty vase, previous vase state and
                                      -- the input as string of numbers

Aferin :) ! Son üç "nedir?
Sygmei

@Sygmei İki dize f "0000000000" "", aralarında boşluk kalmanıza gerek yok. Ben koda bir açıklama ekledim.
Laikoni

Güzel, şimdi anlaşılması kolay :)
Sygmei
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.