PNZ (Adivina 3 dígitos únicos en orden)

15

De un desafío en un libro de programación hace mucho tiempo, PNZ es un juego donde el usuario debe adivinar tres dígitos únicos en el orden correcto.

reglas :

  1. Se genera un número aleatorio de 3 dígitos sin dígitos repetidos. (Esto es lo que el usuario intenta adivinar)
  2. El usuario ingresa una conjetura de 3 dígitos, que será evaluada por el programa.
  3. Imprima una "P" por cada dígito correcto en un lugar correcto.
  4. Imprima una "N" por cada dígito correcto en un lugar incorrecto.
  5. Imprima una "Z" solo si no hay dígitos correctos.
  6. Continúe aceptando entradas hasta que todos los dígitos estén correctos y en el lugar correcto, luego envíe "PPP" seguido del número de conjeturas que tomó en una nueva línea.

Nota :

  • Un "dígito correcto" significa que uno de los dígitos en la conjetura también es uno de los dígitos en el número aleatorio de 3 dígitos.

  • Un "lugar correcto" significa que es un "dígito correcto" Y está en el mismo lugar que el número aleatorio de 3 dígitos.

  • El orden de salida debe ser primero "P", luego "N" o solo "Z" si nada es correcto.

  • Si una entrada contiene dígitos que se repiten, "P" tiene prioridad sobre la "N" (Ejemplo: Number: 123 Input: 111 Output: P)

  • (OPCIONAL) Las entradas que no tienen exactamente 3 dígitos de longitud no deben evaluarse, ni contar para el total acumulado de conjeturas

Ejemplo si los dígitos generados fueron 123

> 147
P
> 152
PN
> 126
PP
> 123
PPP
4

Ejemplo si los dígitos generados fueron 047

> 123
Z
> 456
N
> 478
NN
> 947
PP
> 047
PPP
5

Este es CodeGolf, por lo que gana el programa más corto.

Señor público
fuente
Bienvenido a PPCG! Este es un gran primer desafío, pero me temo que lo hemos hecho antes. El juego también se conoce como Mastermind. Aquí está el desafío existente, pero no puedo decidir si cerrar el viejo o el nuevo. Estoy un poco inclinado a cerrar esto, pero dejaré que la comunidad decida.
Martin Ender
@ MartinBüttner Ah, ese es mi mal. Parece un problema bastante similar. Estaré de acuerdo contigo y dejaré que la comunidad decida.
Mr Public
@ MartinBüttner ¿Cuál es el criterio aquí? ¿En qué medida debe tener prioridad la anterior?
Luis Mendo
2
@ MartinBüttner Creo que entre exigir que los dígitos sean únicos y la naturaleza interactiva, este desafío es lo suficientemente distinto como para que valga la pena.
AdmBorkBork
@LuisMendo No creo que haya un criterio oficial, porque cerrar los viejos desafíos es algo bastante reciente. Mi criterio personal es "qué desafío es mejor y / o más básico".
Martin Ender

Respuestas:

5

JavaScript (ES6) 184 187 195

Editar guardado 8 bytes thx @Neil Editar guardado 3 bytes thx @ user81655

(saltos contados como 1 byte)

d=[...'0123456789']
x=[10,9,8].map(l=>d.splice(Math.random()*l,1))
for(c=p=a='';!p[2];++c)g=prompt(a),n=p='',x.map((d,i)=>d-g[i]?~g.search(d)?n+='N':0:p+='P'),a=p+n||'Z'
alert(a+' '+c)

Prueba

d=[...'0123456789']
x=[10,9,8].map(l=>d.splice(Math.random()*l,1))
for(c=p=a='';!p[2];++c)
  g=prompt(a),
  n=p='',
  x.map((d,i)=>
        d-g[i]?~g.search(d)?n+='N':0:p+='P'
       ),
  a=p+n||'Z'
alert(a+' '+c)

edc65
fuente
Creo que d.splice(v=Math.random()*-~l,1)te ahorra 5 o incluso 8 bytes (a costa de un poco de rendimiento).
Neil
@Neil Rechacé el empalme cuando comencé a encontrar una solución, me pareció largo. Ahora lo intentaré nuevamente
edc65
1
@ user81655 bien, gracias. Realmente un elenco extraño
edc65
3

PowerShell v2 +, 177 231 168 bytes

$g=-join(0..9|Random -c 3);for($c=0;$o-ne"PPP";$c++){$n=$p='';$i=read-host;$o=-join(0..2|%{((("","N")[$i.IndexOf($g[$_])-ge0]),"P")[$g[$_]-eq$i[$_]]}|sort -des);($o,"Z")[!$o]}$c

Curiosamente, pude jugar golf a la versión fija para que tuviera una longitud más corta que la versión no fija ... oO

¡Muchas gracias a @ edc65 por su ayuda e inspiración!

Explicación:

$g=-join(0..9|Random -c 3)   # Create an array @(0,1,2,...9) and choose 3 distinct elements
for($c=0;$o-ne"PPP";$c++){   # Loop until output = "PPP", incrementing $count each time
  $i=read-host               # Read input from the user

  $o=-join(0..2|%{((("","N")[$i.IndexOf($g[$_])-ge0]),"P")[$g[$_]-eq$i[$_]]}|sort -des)
       # OK, this is the convoluted part. We're constructing an array of "N", "P", or "",
       # sorting them by descending order (so the P's are first), and then joining them
       # together into a string. The array is constructed by essentially an if/elseif/else
       # statement that is evaluated three times thanks to the 0..2|%{} loop.
       # Starting from the innermost, we choose between "" and "N" based on whether the
       # input number has the current-digit of the secret number somewhere within it. We
       # then choose between that or "P" based on whether it's the _current_ digit of the
       # user input number.

  ($o,"Z")[!$o]
       # Here we output either $o from above or "Z" based on whether $o is empty
}
$c                           # The loop finished (meaning the user guessed), output $count

Ejemplo de ejecución:

PS C:\Tools\Scripts\golfing> .\pnz.ps1
123
N
111
Z
222
P
452
PN
562
NN
275
PN
258
PPP
7
AdmBorkBork
fuente
¿Cómo verifica que los dígitos no se repitan?
edc65
@ edc65 Salida corregida. Eso fue caro. Todavía estoy trabajando para jugar más al golf, pero no tengo esperanzas ...
AdmBorkBork
Estoy seguro de que puedes hacerlo mejor. Aproveche el hecho de que la suposición puede tener repeticiones, pero el número que tiene que adivinar no. Por ejemplo, en mi respuesta empiezo desde cada dígito para adivinar y
verifico
@ edc65 Gracias por la inspiración y la asistencia: ¡la versión fija de golf fue más corta que la versión no fija! : D
AdmBorkBork
Ahora estoy obligado a
votar
0

R , 178166 bytes

y=!(s<-sample(48:57,3))
while(any(y!=s)){F=F+1
y<-utf8ToInt(readline())
cat(rep("P",p<-sum(y==s)),rep("N",n<-sum(y%in%s)-p
),if(!(n+p))"Z","
",if(all(y==s))F,sep="")}

Pruébalo en línea!

El enlace TIO es solo para el recuento de bytes: intente esto en su consola R (o avíseme si hay una opción alternativa).

Vea la historia para una versión menos legible y más legible.

JayCe
fuente