The Golfer Adventure - Chapter 1: The vase


13

L'avventura del golfista

Questa è la prima sfida! In seguito ci saranno più sfide che richiederanno i dati della sfida precedente :)

Capitolo 1: Il vaso

Immaginiamo un minuto .. Sei un Dio potente, i tuoi poteri sono illimitati ma richiedono una cosa: Anime. Ogni anima è qui rappresentata da un byte, ogni byte che usi sacrifica un'anima. Quindi l'obiettivo è ovviamente quello di salvare il maggior numero di persone sacrificando il minor numero di anime.

La tua prima sfida è salvare un piccolo villaggio, il diavolo è disposto a non distruggere l'intero villaggio se risolvi la sua sfida.

La sfida :

Hai un vaso verticale che può contenere esattamente 10 cose (Aria inclusa). Se metti qualcosa in quel vaso, la gravità farà cadere quella cosa sul fondo. Se il vaso è già pieno (ed è sempre pieno se lo consideri "pieno d'aria"), l'ingresso sostituirà l'elemento nella parte superiore del vaso.

Ecco il set di cose consentite:

  • Aria 0 /
  • Una pietra 1 / -
  • Una foglia 2 / ~
  • Una bomba 3 / x

Se c'è una roccia o una foglia sopra "Una bomba", esploderà e distruggerà la cosa sopra di essa.

L'ingresso è l'elenco delle cose che metterai nel vaso ogni turno.

Esempio: 11231: metterai 2 pietre, poi una foglia, poi una bomba e infine un'ultima roccia.

Quando il vaso è statico, puoi iniziare a contare con la seguente regola:

  • Rock aggiunge 1 unità all'accumulatore
  • Leaf moltiplica l'accumulatore per 2
  • La bomba diminuisce l'accumulatore di 1
  • L'aria non fa nulla

(Devi iniziare a contare dalla cima del vaso)

Ecco la simulazione che otteniamo usando "11231" come input:

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

E l'output sarà 2 (calcolato come ((0 x 2) + 1) + 1) Non è necessario stampare tutti gli stati del vaso!

Il programma di base (Python3)

Puoi eseguirlo per capire come funziona.

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)

Versione golfizzata (Python3, senza display Vase): 360 byte = 360 punti

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)

Se si desidera verificare se il programma funziona correttamente, è possibile verificare questo input: 12122111131

La risposta corretta è 43 :) (Grazie Emigna)

Ora per i punti:

  • (x) punti in cui: x è la quantità di byte necessari per scrivere il programma. Se rispondi dopo aver pubblicato la prossima sfida, i punti per questa sfida non verranno aggiunti al tuo totale di punti.

L'obiettivo è mantenere un numero minimo di punti durante l'intera sfida :) Se salti una parte della sfida, per impostazione predefinita avrai (wx + 1) punti per la parte saltata (dove wx è il punteggio peggiore per quella sfida).

Dati che saranno richiesti per la prossima sfida:

Uscita quando input = 10100000200310310113030200221013111213110130332101

Campione attuale: Emigna

Buona fortuna a tutti !


2
Cosa significa "può contenere esattamente 10 cose"? "Air" conta come una cosa? L'input è garantito in modo tale che il vaso contenga solo 10 cose (non lo vedo soddisfatto nell'implementazione di riferimento)? Anche l'input che produce i dati per la prossima sfida sembra avere più di 10 cose (anche se l'aria è come nulla e le bombe fanno esplodere la prossima cosa sopra l'aria ci saranno 14 cose, penso).
Jonathan Allan,

1
Un input 333costruisce un vaso [0, 0, 0, 0, 0, 0, 0, 3, 3, 3]nel tuo algoritmo golfizzato e quindi un punteggio di -3, ma non dovrebbe essere [0, 0, 0, 0, 0, 0, 0, 0, 0, 3]e quindi un punteggio -1secondo le tue specifiche?
Laikoni,

2
@Laikoni Ho dimenticato di specificare che le bombe non esplodono quando una bomba si trova sopra un'altra, grazie!
Sygmei,

1
L'output per 10100000200310310113030200221013111213110130332101 sembra essere 22, giusto?
Erik the Outgolfer,

2
L'aggiunta di un caso test complicato come 12122111131 potrebbe essere una buona idea.
Emigna,

Risposte:


5

Python 2 - 208 191 185 180 172 164 156 byte

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

La rottura è che rimuove l'aria e le bombe se è in pila quindi conta.

EDIT: ho scambiato con Python 2 per salvare un byte, ma ora l'ingresso dovrebbe essere messo tra parentesi graffe come '3312123'

EDIT2: Sono anche un po 'orgoglioso del conteggio dell'accumulatore

EDIT3: Grazie per tutti i tuoi suggerimenti non avrei mai pensato di poterlo ottenere così in basso


Bella prima risposta! Stavo pensando anche con Python ma poco tempo oggi. Penso che avresti comunque battuto il mio approccio.
ElPedro,

Grazie per il gentile commento :) La prima volta che sto giocando a code golf e devo dire che è abbastanza divertente.
Pâris Douady,

Utilizzare t[:10][::-1]invece di reverse()salvare 4 byte e forse utilizzare Python 2 per salvare una parentesi sul print? Arriva a 5 anime in più salvate per me :)
ElPedro,

Nessun Python2 per me dato che avrei dovuto lanciare input () per str per farlo funzionare, uccidendo altre 5 anime. Bello il [:: - 1]
Pâris Douady,

a proposito, non ho visto nulla nella domanda che dice che l'input puo 'essere racchiuso tra virgolette. Dice semplicemente "L'ingresso è l'elenco delle cose". Funziona in Python 2 :)
ElPedro il



3

Python 2, 150 146 byte

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

Grazie a Pâris Douady per la formula punti e per il salvataggio di 4 byte.


Hai preso la mia formula per il conteggio del punto? Ad ogni modo bella soluzione, mi hai battuto ed è molto più pulito. inoltre puoi salvare alcuni byte facendo for c in input()direttamente
Pâris Douady il

2

Javascript, 267 264 249 anime sacrificate

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}

Versione modificata, perché la precedente era errata per input più grandi. Lo ho ulteriormente risolto trasformandolo string.prototype.replace()in una chiamata di funzione accessibile dall'array. Spiegazione:

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');ritorna 2. Provalo online


10100000200310310113030200221013111213110130332101 non restituisce il buon risultato :) Sei vicino però :)
Sygmei

@Sygmei Lo so, e ne ho fatto il debug della merda, ma non riesco a scoprire perché. Puoi vedermi in chat?
Steenbergh,

1

Haskell, 221 202 181 177 166 anime byte

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])%)

Provalo su ideone . Prende gli elementi come elenco intero.

Uso:

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

(Modifica: precedente) Spiegazione:

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

Buon lavoro :) ! Quali sono gli ultimi tre "?
Sygmei,

@Sygmei sono due stringhe f "0000000000" "", semplicemente non hai bisogno di spazi tra loro. Ho aggiunto una spiegazione al codice.
Laikoni,

Bello, più facile da capire ora :)
Sygmei
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.