¿Cuánta agua queda?

29

Aquí en California, estamos en una sequía, por lo que necesitamos saber cuánta agua nos queda para poder conservar la mayor cantidad de agua posible.

Debido a que el suministro de agua es limitado, su código deberá ser lo más breve posible.

Ejemplos

|   |
|   |
|~~~|
|___|

Output: 0.5
|~~~~~|
|     |
|     |
|_____|

Output: 1
|  |
|__|

Output: 0 (or bonus)

Especificación

La entrada consistirá únicamente en todos: |_ ~y nuevas líneas. Todos los de arriba ~se consideran aire; _, los espacios de abajo ~y en ~sí mismos se consideran agua. El porcentaje de agua restante es por computadora water / (air + water). Su salida debe tener una precisión de 4 decimales (a menos que elija el porcentaje de bonificación). La entrada siempre será rectangular. El ~solo estará en una línea, si está en alguna. La entrada también puede tener opcionalmente un avance de línea final si lo desea.

Prima

Si opta por ambos bonos, el bono de -15% se aplica antes del bono de -35

-35 bytes de bonificación: si su código imprime "Esta cabra de sequía fuera de control", en lugar de 0 cuando la salida es 0

-15% de bonificación: si genera un porcentaje.

Para hacer esto, debe cambiar el lugar decimal dos lugares a la izquierda, recortar los ceros a la izquierda y agregar un %a al final. Los ceros finales (máximo 2) se permiten siempre que no afecten el valor. 0.5-> cualquiera de:50.00% 50% 50.0%

Downgoat
fuente
28
" Debido a que el suministro de agua es limitado, su código deberá ser lo más breve posible " . Uhhh, está bien ... ¿Supongo?
Fatalize
14
@Fatalize: no es de conocimiento común fuera del estado, pero las computadoras basadas en lógica fluídica son extremadamente populares en California. Escuché que están tratando de ver si pueden encontrar una alternativa a base de almendras en estos días.
JohnE
10
@JohnE que probablemente explica por qué hay una sequía allí ahora
hargasinski
1
Ustedes saben que las computadoras fluídicas no usan agua, ¿verdad? Al igual que las computadoras eléctricas no causan escasez de electrones.
user253751
¿Es esto: |~~~|(sin guión bajo) entrada válida?
edc65

Respuestas:

16

Pyth - 17 46 45 52 * .85 - 35 = 9.2 bytes

Filtra la entrada (¡con el nuevo #filtro meta-op!) Para una línea con ~ella, luego la indexa a la entrada y luego la divide por la longitud de la entrada. Si no hay ninguno con ~, produce errores y activa la cláusula except de .xe imprime la cadena.

.x+*100-1cxK.zh@#\~KlK\%." u(C$éáPãbÉãç*îÂe[W

Pruébelo en línea aquí .

Maltysen
fuente
10

Python 3, 37 bytes

lambda x:1-(x+'|~').find('|~')/len(x)

Sin bonificaciones Toma una cadena de entrada con nuevas líneas, incluida una nueva línea final.

Veamos por qué funciona la fórmula. La fracción de agua es el complemento de la fracción de aire, que derivaremos.

frac_water = 1 - frac_air

Numerando las filas 0, 1, 2, ..., tenemos

frac_air = water_row_index / num_rows 

Lo mismo es cierto si ambos se multiplican por el ancho de cada fila, contando nuevas líneas, que se simplifican a expresiones en el número de caracteres.

frac_air = (width * water_row_index) / (width * num_rows)
         = water_row_start_char_index / num_chars

La puesta en fila de agua se encuentra buscando en la cadena de entrada xpara |~, y el número de caracteres es sólo la longitud.

frac_air = x.find('|~') / len(x)

Finalmente, para que las entradas sin agua funcionen, agregamos una fila de agua ficticia de principio |~a fin antes de buscar, lo que hace que parezca que el nivel de agua es 0.

Las bonificaciones no parecían valer la pena. Lo mejor que obtuve en la cadena uno es 73-35 = 38:

lambda x:['This drought goat out of hand',1-x.find('|~')/len(x)]['~'in x]
xnor
fuente
7

CJam, 19 17 16 58 * 0.85 - 35 = 14.3 bytes

q'|-_'~#_)\@,d/1\m100*s'%+"This drought goat out of hand"?

Pruébalo en línea

Esta versión recibe ambos bonos. La entrada debe tener una nueva línea final para que esta solución funcione.

Gracias a @ Martin Büttner por guardar 2 bytes.

Explicación:

q       Get input.
'|-     Remove left/right wall, so that position of first ~ in remaining string
        corresponds to the water level.
_       Make a copy.
'~#     Find ~ character.
_)      Make copy of find result, and increment it. This is 0 if the ~
        was not found, and will be used for the bonus condition.
\       Swap original find result to top.
@,      Rotate copy of remaining input to top, and get its length.
d       Convert to double to get float division.
/       Divide the two values. Since the position of the ~ was indexed from
        the top, this is 1 minus the desired result.
1\m     Subtract value from 1, to get the actual result.
100*    Multiply by 100 to get percent.
s       Convert to string.
'%+     Append % sign.
"This drought goat out of hand"
        Push bonus zero string.
?       Ternary operator to pick calculated result or zero string.
Reto Koradi
fuente
5

JavaScript (ES6), 45 (94-15% -35)

Como una función anónima. Usando cadenas de plantilla, hay una nueva línea que es significativa e incluida en el conteo de bytes

Editar 1 byte guardado thx @ user81655

p=>p.split`
`.map((r,i)=>r>'|~'?p=i:q=~i)&&q-p?(1+p/q)*100+'%':'This drought goat out of hand'

Menos golf

p=>(
  p.split('\n') // split in rows
  .map((r,i)=> // execute for each row
    r>'|~'   // look for the water top
      ? p=i  // position of water top in p
      : q=~i // if not water top, set current position (-i-1) in q
  ),
  // at the end,if water top not found, p still contains the input string
  q-p // subtracting the input string I get NaN (that is a falsy value)
  ? (1+p/q)*100+'%' // calc % taking into account the negative sign of q
  : 'This drought goat out of hand' 
)

Fragmento de prueba

F=p=>p.split`\n`.map((r,i)=>r>'|~'?p=i:q=~i)&&q-p?(1+p/q)*100+'%':'This drought goat out of hand'

function Update() {
  var w=+W.value, h=+H.value, t=+T.value,
      b=Array(h).fill().map((r,i)=>'|'+(i==h-1?'_':i==t?'~':' ').repeat(w)+'|').join`\n`  
  O.textContent = b+'\n\n'+F(b)
  
}

Update()
<table>
  <tr><td>Width</td><td><input id=W type=number value=4 oninput='Update()'></td></tr>
  <tr><td>Height</td><td><input id=H type=number value=4 oninput='Update()'></td></tr>
  <tr><td>~~~ at row</td><td><input id=T type=number value=2 oninput='Update()'></td></tr>
</table>  
<pre id=O></pre>

edc65
fuente
1
Hermoso fragmento de prueba y excelente código como siempre. Una sugerencia: Se puede reemplazar p=~icon p=i, &&-pcon &&p-qy 1+~ppara 1+pahorrar 1 byte.
user81655
@ user81655 buena sugerencia, gracias
edc65
4

Par , 57 * 85% - 35 = 13.45 bytes

`This drought goat out of hand`r√″T┐↑⌐'~˦↑↔~÷Zx²*'%↔╡\z_g

Explicación

`This dr...d`  ## 'This drought goat out of hand'
r              ## Read entire input
√              ## Split by newlines
″              ## Duplicate
T              ## Transpose
┐↑             ## Second element of each line
⌐              ## Reverse
'~˦            ## First index of '~'
↑              ## Plus one
↔              ## Swap
~÷             ## Divide by size
Z              ## Assign to z
x²*            ## Multiply by 100
'%↔╡           ## Append '%'
\              ## Array of string and number
z_g            ## If z=0, then string; else, number
Ypnypn
fuente
3

Perl, 70 - 15% - 35 = 24.5 bytes

incluye +1 para -p

 $S[$w|=/~/]++}{$_=$w?100*$S[1]/$..'%':'This drought goat out of hand'

Con comentarios:

$S[ $w |= /~/ ]++                   # $w=0 for air, 1 for having seen water; count element
}{                                  # -n/-p: end the `while(<>){` and begin END block
$_ = $w                             # assign output for -p
  ? 100 * $S[1] / $. . '%'          # $. is $INPUT_LINE_NUMBER
  :'This drought goat out of hand'  # costs 35 aswell, but is effectively more after -15%

  • Versión de 26 + 1 bytes, sin bonificación: 27

    $S[$w|=/~/]++}{$_=$S[1]/$.
    
  • Versión de 34 + 1 bytes, con un 15% de bonificación: 29.75

    $S[$w|=/~/]++}{$_=100*$S[1]/$..'%'
    
  • Versión de 61 + 1 bytes, con bonificación de -35: 27

    $S[$w|=/~/]++}{$_=$w?$S[1]/$.:'This drought goat out of hand'
    
  • Versión de 69 + 1 bytes, ambos bonos: 24.50

    $S[$w|=/~/]++}{$_=$w?100*$S[1]/$..'%':'This drought goat out of hand'
    
Kenney
fuente
2

Javascript, 59.3

Espero que los decimales adicionales estén bien. Asume que no hay nueva línea final.

drought=
// code
a=>(b=-1,e=a.split`
`.map((c,d)=>b=c[1]=='~'?d:b).length,++b?(e-b+1)*100/e+"%":"This drought goat out of hand")

// I/O
var i = document.getElementById("i");
var o = document.getElementById("o");
i.onchange = i.onkeyup = function(){
  o.textContent = drought(i.value);
};

// explanation
inputStr=>(
  tildePosition = -1, // default: not found
  containerDepth =    // if the current line has a tilde, set tildePosition, otherwise
                      // keep current tildePosition
      inputStr.split`\n`.map((line, pos)=> tildePosition = line[1]=='~' ? pos : tildePosition)
    .length,          // assign number of lines (container depth) to containerDepth
  ++tildePosition     // if it's still -1, print the message, otherwise print percent
    ?(containerDepth-tildePosition+1)*100/containerDepth+"%"
    :"This drought goat out of hand")
<textarea id="i"></textarea>
<p id="o"></p>

DankMemes
fuente
1

Haskell, 56 bytes

l=sum.(>>[1])
f i|s<-lines i=l(snd$break(elem '~')s)/l s

Ejemplo de uso: f "| |\n|~~|\n| |\n|__|"-> 0.75.

les una función de longitud personalizada, que es necesaria, porque la construcción lengthdevuelve valores enteros, pero necesitamos valores de coma flotante para la división (haygenericLength que también proporciona esta característica, pero es más larga, y mucho menos la requerida import Data.List). fdivide la entrada ien líneas (-> s) y luego en un par donde el primer elemento es una lista con todas las líneas hasta (y excluyendo) la primera con un ~. El segundo elemento es una lista con el resto de las líneas. El resultado es la longitud del segundo elemento dividido por la longitud des .

Los bonos no dan resultado.

nimi
fuente
1

¡Python es detallado!

Python: 98.45 bytes

(157 * 0.85) - 35 = 98.45 bytes

Esta versión lee de stdin y recoge ambos bonos:

import sys
r=[x[1]for x in sys.stdin.read().split('\n|')]
o="This drought goat out of hand"if'~'not in r else"%g%%"%(100-100.0*r.index('~')/len(r))
print(o)
Nicholas Clark
fuente
2
66 sin bonificaciones:import sys;r=[x[1]for x in sys.stdin];print(1-r.index('~')/len(r))
Blender
¡Agradable! Sin embargo, eso se disparó con la nueva línea final opcional, ¿no? Además, ¿es Python 3 solo por el operador de división?
Nicholas Clark
La nueva línea final opcional depende de usted para incluirla. En cuanto a la división, sí, pero ya lo estás tratando printcomo una función, así que supuse que estabas usando Python 3.
Blender
1

Awk, 72 caracteres - 15% - 35 = 26.2

/~/{w=NR}END{print w?(NR-w+1)/NR*100"%":"This drought goat out of hand"}

Ejecución de muestra:

(Inicial 1;solo se usa en estas muestras para mostrar el tanque "legible para humanos").

bash-4.3$ awk '1;/~/{w=NR}END{print w?(NR-w+1)/NR*100"%":"This drought goat out of hand"}' <<< $'| |\n| |\n| |\n|_|'
| |
| |
| |
|_|
This drought goat out of hand

bash-4.3$ awk '1;/~/{w=NR}END{print w?(NR-w+1)/NR*100"%":"This drought goat out of hand"}' <<< $'| |\n| |\n|~|\n|_|'
| |
| |
|~|
|_|
50%
hombre trabajando
fuente
1

PHP, 92 caracteres - 15% - 35 = 43.2

(88 caracteres en dos bloques de código + 4 caracteres de opciones de línea de comando).

$argn[1]>z&&$w=+$argi;
echo$w?100*($argi-$w+1)/$argi."%":"This drought goat out of hand";

Asume que error_reportingestá configurado por defecto.

(No es gran cosa, solo quería usar el -Ry -Euna vez. Ahora solo -Bqueda).

Ejecución de muestra:

(Inicial echo"$argn\n";solo se usa en estas muestras para mostrar el tanque "legible para humanos").

bash-4.3$ php -R 'echo"$argn\n";$argn[1]>z&&$w=+$argi;' -E 'echo$w?100*($argi-$w+1)/$argi."%":"This drought goat out of hand";' <<< $'| |\n| |\n| |\n|_|'
| |
| |
| |
|_|
This drought goat out of hand

bash-4.3$ php -R 'echo"$argn\n";$argn[1]>z&&$w=+$argi;' -E 'echo$w?100*($argi-$w+1)/$argi."%":"This drought goat out of hand";' <<< $'| |\n| |\n|~|\n|_|'
| |
| |
|~|
|_|
50%
hombre trabajando
fuente
0

QBIC - 116 - 15% = 98.6 bytes

{input S$:S$=MID$(S$,2,1):I=I+1:IF y<1 then x=I
y=y+instr(S$,"~"):IF instr(S$,"_")>0 THEN ?(1-(x-y)/I)*100;"%":END}

Creé QBIC para hacer que QBasic sea más competitivo, pero aún necesita varias mejoras. A partir de ahora, no hay atajos para la captura de errores THEN(que es un descuido bastante grande de mi parte) y input$. Se agregarán en breve.

No pude alcanzar el bono 0, demasiado costoso ... logré imprimir porcentajes.

Muestra en / salida:

? |  |
? |  |
? |~~|
? |__|
 50 %

El programa lee la entrada de forma interactiva. Cuando detecta el fondo del lago ( _), imprime el porcentaje y se cierra. Probado para contenedores llenos y vacíos también.

Editar: para mostrar cómo se ha ampliado QBIC durante el último año, aquí está el mismo programa escrito para el intérprete actual:

{_?A=$MID$|(A,2,1)#~|#_| i=i+1~j<1|k=i]j=j+instr(A,B)~instr(A,C)|?(1-(k-j)/i)*100,@%|_X

87 bytes, porcentajes de impresión, es una puntuación de 74.

Steenbergh
fuente