Acqua trattenuta in una scultura esagonale a bacchetta


22

Ho un mucchio di aste esagonali incollate insieme in una strana scultura. Le aste sono lunghe da 1 a 99 centimetri (cm) e 1 cm quadrato nell'area della sezione trasversale. Tutte le aste sono incollate su una faccia esagonale ad almeno un'altra asta. Le aste sono tutte allineate sul bordo inferiore.

Dopo alcune forti piogge, la scultura è piena d'acqua. Quanta acqua contiene?

Ingresso

Il tuo programma dovrebbe leggere (tramite stdin o un file) un numero di righe costituite da coppie di spazi e coppie di cifre che specificano la lunghezza delle aste in questo formato:

  aa  bb
cc  dd  ee
  ff  gg

Ogni asta (come dd qui) è incollata ad un massimo di 6 aste circostanti, come mostrato negli esempi. Le aste mancanti sono buchi e non raccolgono acqua. Ad esempio, l'input

  04  04
04  01  03
  04  04

rappresenterebbe la seguente scultura:

inserisci qui la descrizione dell'immagine

L'asta centrale è in altezza 1(non ho trovato un buon angolo in cui sia visibile anche l'asta). Ora la colonna sopra quell'asta poteva contenere 2 cm di acqua, prima che traboccasse 3sull'asta sulla destra. Dal momento che nessuna delle altre canne può contenere acqua sopra di loro, la risposta sarebbe 2. Ecco altri due esempi complessi:

Example 2:
55  34  45  66
  33  21  27
23  12  01  77
  36  31  74
answer = 35 (  2 on top of 21 
             +11 on top of 12
             +22 on top of 01, before everything overflows over 23)

Example 3:
        35  36  77  22                      23  32  54  24
      33  07  02  04  21                  54  07  07  07  76
    20  04  07  07  01  20              54  11  81  81  07  76
  20  67  67  22  07  01  78          54  07  81  07  81  09  76
20  67  07  67  22  22  07  44  55  54  07  81  07  07  61  07  20
  67  57  50  50  07  07  14  03  02  15  81  99  91  07  81  04
67  07  50      50  87  39  45  41  34  81  07  07  89  07  81  79
  67  07  50  50  07  07  07  27  07  27  81  07  07  79  81  78
20  67  67  07  07  07  07  99  33  46  02  81  07  07  81  01  20
  33  07  07  01  05  01  92          20  02  81  07  81  15  32
    22  07  20  20  07  20              63  02  80  81  15  32
      45  20  01  20  39                  20  15  07  15  32
        23  20  20  29  43  21  18  41  20  66  66  43  21
      90                  99  47  07  20
    50                      20  02  48
  70                          56  20
                                90

answer = 1432

Produzione

Il programma dovrebbe generare un unico numero intero che dia il volume di acqua in centimetri cubi.

Punto

Il tuo punteggio è il conteggio dei byte del tuo codice sorgente. Vittorie più basse.

Le scappatoie standard sono vietate come al solito.

Questo puzzle è stato ispirato da una domanda SPOJ .


4
Ho avuto difficoltà a visualizzarlo le prime due volte che l'ho letto, quindi mi sono liberato di aggiungere un diagramma e un po 'più di spiegazione per il primo esempio. Spero non ti dispiaccia.
Martin Ender,

Questo è molto simile alle altre sfide che coinvolgono forme che si riempiono di acqua.
FUZxxl

2
@FUZxxl abbiamo altre sfide del genere?
Ottimizzatore

1
@FUZxxl Ricordo solo questa sfida , che è molto diversa.
Martin Ender,

@Optimizer Questo è in qualche modo simile.
Zgarb,

Risposte:


4

Python 2, 222 byte

import sys
y=h=v=0;B={}
for l in sys.stdin:
 z=y;y+=2j
 while l:
    if"0"<l:B[z]=int(l[:2])
    l=l[2:];z+=1
while B:C=B;B={b:B[b]for b in B if(h<B[b])+sum(3>abs(c-b)for c in B)/7};a=C==B;h+=a;v+=a*sum(h>B[b]for b in B)
print v

Legge l'input tramite STDIN e scrive il risultato su STDOUT.

Spiegazione

Iniziamo da zero e aumentiamo gradualmente il livello dell'acqua nel modo seguente: Supponiamo che il livello dell'acqua sia h e che vogliamo aggiungere 1 centimetro d'acqua. Chiameremo esagoni di altezza h o inferiore, quelli che stanno per andare (o sono già) sott'acqua, " sommersi ". L'acqua si riverserà attraverso qualsiasi esagono sommerso che non è circondato da sei vicini. Eliminiamo tutti questi esagoni; ovviamente, ora alcuni altri esagoni sommersi potrebbero avere meno di sei vicini e devono anche essere eliminati. Continuiamo in questo modo fino alla convergenza, cioè fino a quando tutti gli esagoni sommersi rimanenti hanno esattamente sei vicini. A questo punto aggiungiamo il numero di esagoni sommersi (il volume d'acqua ottenuto) al conteggio totale e incrementiamo il livello dell'acqua.

Alla fine, tutti gli esagoni saranno stati eliminati e ci fermeremo.


Dovresti essere in grado di radere un personaggio usando -3<c-b<3 invece di 3>abs(c-b).
DLosc

@DLosc Ah, ma sono numeri complessi;)
Ell

Affascinante. Non l'ho capito.
DLosc

2

Ruby 299

f=->i{s={}
l=i.lines
y=0
l.map{|r|x=0
r.scan(/../){s[[x,y]]=[v=$&.to_i,v<1?0:99];x+=1}
y+=1}
loop{break if s.map{|c,r|x,y=c
m = [[-1,-1],[1,-1],[-2,0],[2,0],[1,-1],[1,1]].map{|w,z|s[[x+w,y+z]]}.map{|n|n ?n[0]+n[1]:0}.min
r[1]=[0,m-r[0]].max if r[0]+r[1]>m&&r[1]>0}.none?}
s.map{|c,r|r[1]}.reduce :+}

Breve descrizione dell'algoritmo:

  • analizza l'input e per ogni barra salva una matrice a due elementi della forma [rod_height, water_height]
  • le aste sono posizionate in un hash e indicizzate dalle loro coordinate x, y
  • la parte che perde acqua tiene conto delle altezze dell'asta / acqua dei vicini immediati

Una versione leggermente più leggibile è disponibile qui: http://ideone.com/cWkamV

Esegui la versione del golf online con i test: http://ideone.com/3SFjPN


scanaccetta un argomento a blocchi. Si può solo fare scan(/../){...}. Invece di 'scan (/../) mappa {| v | ...} . (You don't need the | v | `perché All'interno del scanblocco è possibile $&, $1e così via)
Jordan

@Jordan Grandi osservazioni! Grazie!
Cristian Lupascu,
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.