¿Puedo establecerme?

23

En el juego de mesa The Settlers of Catan , hay cinco tipos de recursos: Brick, Log, Ore, Wheat y Sheep. La construcción de un asentamiento cuesta un ladrillo, un tronco, un trigo y una oveja. Sin embargo, también puede intercambiar cuatro recursos idénticos para obtener un recurso de un tipo diferente. Por ejemplo, si tuviera cuatro minerales en la mano, podría intercambiarlos y obtener una oveja.

Su trabajo es determinar si puedo o no construir un acuerdo, dada mi mano.

Tu tarea

De entrada será una secuencia de las letras B, L, O, W, y S, tomada en cualquier formato razonable. Estas letras corresponden a los cinco tipos de recursos dados anteriormente. Debe indicar si tengo o no los recursos necesarios para construir un acuerdo, teniendo en cuenta la posibilidad de negociar cuatro de un tipo.

Este es el , por lo que gana el código más corto en bytes.

Notas

  • No tiene que dar salida a las operaciones que necesito realizar o cuántos asentamientos podría construir. Un simple "sí" o "no" servirá.
  • Es posible que no se supone que la entrada está en ningún orden específico. En particular, no puede suponer que los recursos del mismo tipo están agrupados, por lo que OBLSOes una entrada válida.
  • Este es , por lo que puede usar cualquier valor que quiera que signifique "sí" y "no", siempre que los dos valores elegidos sean distintos y consistentes.
  • Las únicas reglas que nos interesan aquí son las enumeradas anteriormente. Las reglas más complicadas de los Colonos de Catan, como comerciar con otros jugadores o en puertos, no son relevantes aquí.
  • Los caracteres de entrada ( B, L, O, W, S) pueden ser sustituidos por otros valores si es más fácil para su idioma particular de la elección, siempre y cuando hay cinco entradas distintas. Si utiliza otros valores de entrada, especifíquelos en su respuesta.

Ejemplos

BLWS -> Yes
OOOOWLB -> Yes (trade four O for a S)
OOW -> No
BBBO -> No
(empty input) -> No
BBBBLW -> No
BBBBBLW -> Yes (trade four B for a S)
OOOOOOOOOOOOOOOO -> Yes (sixteen O; trade for B, L, W, S)
BLBLBLBLBL -> Yes (trade L for W and B for S)
BLSWBLSWBLSW -> Yes (extra, unused resources are ignored)
Silvio Mayolo
fuente
13
"Construir un asentamiento cuesta un ladrillo, un tronco, un trigo y una oveja". Sí, para realizar el ritual de construir un asentamiento, necesitas una oveja. ¿Me pregunto por qué no hay vegetarianos?
Okx
55
@Okx, la oveja da la leche que acompaña al pan del trigo para alimentar a los constructores mientras construyen (se llevan a las ovejas al final como pago). Ningún animal
resultó
¿Está bien que el programa requiera que se ordene la entrada?
NieDzejkob
@NieDzejkob No, requerir un pedido está específicamente prohibido. Su programa debe estar preparado para manejar cualquier secuencia de los cinco recursos.
Silvio Mayolo
@SilvioMayolo lo siento, no sé cómo me perdí eso
NieDzejkob

Respuestas:

16

Python 2 , 54 bytes

lambda s:sum((s+"BLSW"*3).count(n)/4for n in"BLSWO")>3

Pruébalo en línea!

Para cada uno de nuestros recursos, contamos el número de "libertades" otorgadas al tener n de ese recurso. Una libertad representa una oportunidad para llenar una de las ranuras de ladrillos, troncos, trigo y ovejas que necesitamos llenar para establecernos, teniendo en cuenta el hecho de que podemos convertir nuestros recursos.

Para todos los BLSW, tener uno de los recursos nos da esa libertad, y cada exceso adicional de 4 nos da otro. La regla de contar la libertad es así:

* Having 1 brick/log/wheat/sheep gives 1 freedom.
* Having 5 bricks/logs/wheat/sheep gives 2 freedoms.
* Having 9 bricks/logs/wheat/sheep gives 3 freedoms.
* 

Entonces n ladrillos / troncos / trigo / ovejas dan ⌊ (n + 3) / 4⌋ libertades.

Para los minerales, solo cuenta el exceso de foursomes. La regla de contar la libertad es así:

* Having 4 ores gives 1 freedom.
* Having 8 ores gives 2 freedoms.
* Having 12 ores gives 3 freedoms.
* 

Así n minerales dar ⌊n / 4⌋ libertades.

Teorema: podemos resolver si y solo si tenemos ≥ 4 de tales "libertades".

Entonces contamos nuestras libertades y verificamos si hay ≥ 4 de ellas. Para manejar el conteo de minerales como ⌊n / 4⌋ pero otros recursos ⌊ (n + 3) / 4⌋, inflamos artificialmente los recuentos de los otros recursos en 3 y luego contamos ⌊n / 4⌋ para todos ellos. Hacemos esto mediante el mapeo en (s+"BLSW"*3).countlugar de s.count.

Prueba :

  • Supongamos que podemos resolver. Luego, para cada uno de [B, L, S, W], o (a) usamos 1 de ese recurso que ya teníamos, o (b) sacrificamos 4 de algún otro recurso (incluidos los minerales) para crearlo. En cualquier caso, contamos al menos 1 libertad según las reglas anteriores. Entonces tenemos ≥ 4 libertades.

  • Supongamos que tenemos 4 libertades, k de las cuales se deben a "excesos" (cada libertad de minerales es un exceso, y cada libertad de otros recursos más allá del primero también lo es) y 4 −k de los cuales son testigos de poseer al menos uno ladrillo / tronco / trigo / oveja (el que dio la "primera libertad"). Luego, llenamos las ranuras de 4 k con el ladrillo / tronco / trigo / oveja que nos dio nuestra primera libertad, y llenamos las ranuras k restantes al convertir nuestros excesos. Los 4 espacios están llenos y podemos resolver. Obviamente, aún podemos hacer esto si tenemos más de 4 libertades.

Esta prueba apesta, pero tengo sueño. Estoy seguro de que hay una mejor explicación.

Lynn
fuente
2
Así por ejemplo ses OOOOBLW, se llega a una sum(n/4for n in map(("OOOOBLWBBBLLLSSSWWW").count,"BLSWO"))>3... así que para cada uno de los BLOWSque cuente cuántas veces que aparece en esa cadena de arranque de "BLWS"*3, a continuación, resumir,.
Pureferret
2
¡Precisamente! (La cadena es "OOOOBLWBLSWBLSWBLSW", en realidad, pero los recuentos son los mismos, por supuesto.)
Lynn
¡El mapa de Python estar 'al revés' siempre me confunde!
Pureferret
El espacio entre in"BLSWO"es innecesario en Python, ¿no? Parece trabajar en TIO al menos ..
Kevin Cruijssen 05 de
8

Python 2 ,  52  51 bytes

-1 byte gracias a Luke (reemplazar >=0con <0, invirtiendo el False/ Trueresultados)

lambda h:sum(~-(h+"O").count(c)/4for c in"BOWLS")<0

Una función sin nombre que toma una cadena de los caracteres B , O , W , L y S (como en el OP) y regresa Falsesi puede resolver o Trueno.

Pruébalo en línea! (obliga a la salida a layes/nodel OP).

¿Cómo?

Este es un puerto de mi respuesta Jelly. Necesitamos compensar los B , W , L o S que faltan del resto después de usar uno de cada uno de ellos. Como tal, podemos agregar un O adicional a nuestra mano, luego reducir todos los recuentos por uno, luego dividir todos los recuentos entre cuatro y luego sumar; si el resultado es cero o más, podemos resolver (ya sea porque no faltaron los recursos necesarios) o porque podemos comerciar para adquirir los que faltan).

lambda h:sum(~-(h+"O").count(c)/4for c in"BOWLS")<0
lambda h:                                           - a function that takes h (a string)
                                 for c in"BOWLS"    - for each letter, c, in "BOWLS":
                h+"O"                               -   append "O" to h
               (     ).count(c)                     -   count c instances
              -                                     -   negate
             ~                                      -   bitwise not (this is -x-1)
                               /4                   -   integer divide by 4
                                                    -    (NB: -1 and 0 are not affected)
         sum(                                   )   - sum the five values
                                                 <0 - less than zero? (inverted result)
Jonathan Allan
fuente
¿Qué tal usar Falsepara 'yes'y Truepara 'no'? Entonces podría cambiar >=a <, ahorrando 1 byte.
Lucas
¡Prefiero su elección de ordenamiento de recursos a la de la pregunta!
Neil
7

Pyth , 14 bytes

gsm/t/+Q4d4U5Z

Pruébalo aquí! o Verificar todos los casos de prueba.

Pyth ,  31 27 17  16 bytes

<3s/R4/L+Q*3U4U5

Verificar los casos de prueba.

¿Cómo funcionan estos?

Explicación # 1

gsm/t/+Q4d4U5Z   - Full program.

  m        U5    - Map over the range [0, 5) with a variable d.
      +Q4        - The input, with a 4 appended (this corresponds to O)
     /   d       - Count the occurrences of the current value in ^.
    t            - Decrement.
   /      4      - Integer division by 4.
 s               - Sum
g            Z   - Is non-negative (is the sum ≥ 0)?  
                 - Output implicitly.

Explicación # 2

<3s/R4/L+Q*3U4U5   - Full program.

          *3U4     - The range [0, 4) repeated 3 times.
        +Q         - The input with ^ appended.
      /L      U5   - Count the occurrences of each element in [0, 5) in ^.
   /R4             - Integer division of each by 4.
  s                - Sum.
<3                 - Is higher than 3?
                   - Output implicitly.

Estos son los códigos utilizados por mi programa:

B -> 0
L -> 1
S -> 2
W -> 3
O -> 4
Sr. Xcoder
fuente
+%ld4/ld4->s.Dld4
Erik the Outgolfer
Oh, está bien entonces.
Erik the Outgolfer
Creo que //Q4 4puede ser, /Q16pero no estoy muy seguro ...
Erik the Outgolfer
@EriktheOutgolfer Era inválido ... se produce un error de BBBO, por ejemplo
el Sr. Xcoder
@EriktheOutgolfer No, es contar las ocurrencias de 4y dividir por 4.
Sr. Xcoder
6

Jalea ,  13  12 bytes

;5ċЀ5’:4S>-

Un enlace monádico que acepta una lista de números que representan los recursos que posee y que devuelve 1si puede establecerse o 0no.

Los recursos son 1, 2, 3, 4, 5donde 5representa el mineral .

Pruébalo en línea! o vea el conjunto de pruebas (usando el OP IO).

¿Cómo?

La idea es contar primero los recursos por tipo, luego reducir todos los recuentos de B , L , W y S en uno: si no contamos ninguno para ninguno de estos cuatro, ahora tendrán entradas de -1 ; necesitamos adquirir ellos de nuestros recursos restantes (Esto en realidad se logra agregando un O ( 5) adicional y reduciendo los cinco recuentos en 1 ). A continuación, dividimos todos estos valores entre cuatro para ver cuántas unidades podemos intercambiar con cada uno de nuestros recuentos restantes por tipo de recurso sin afectar los recuentos -1 y 0 (tenga en cuenta que -1 dividido entre cuatro es-1 , no 0 ). Finalmente, sumamos los valores y verificamos si el resultado es mayor o igual a cero (aquí se puede usar mayor que -1 ya que siempre tenemos enteros).

;5ċЀ5’:4S>- - Link: list of numbers (BLWSO:12345) e.g. [3,2,2,2,2,2,5,5,5,5] (WLLLLLOOOO)
;5           - concatenate a five                       [3,2,2,2,2,2,5,5,5,5,5]
     5       - literal 5
   Ѐ        - map across implicit range(5) = [1,2,3,4,5]:
  ċ          -   count                                  [ 0, 5, 1, 0, 5]
      ’      - decrement (vectorises)                   [-1, 4, 0,-1, 4]
       :4    - integer divide by four                   [-1, 1, 0,-1, 1]
         S   - sum                                      0
           - - literal -1                              -1
          >  - greater than?                            1
Jonathan Allan
fuente
5

Java 8, 101 bytes

Lambda de int[]a boolean. Asignar a Function<int[], Boolean>.

a->{int h,f[]=new int[5],i=0;for(int x:a)f[x]++;for(h=f[4]/4;i<4;)h+=--f[i]>>-1|f[i++]/4;return~h<0;}

Pruébalo en línea

Entrada y salida

La entrada es una matriz de enteros de 0 a 4, inclusive. 4 representa el mineral, y las otras asignaciones son irrelevantes. Mis casos de prueba son traducciones directas de aquellos en la pregunta, con 0 como Brick, 1 como Log, 2 como Wheat y 3 como Sheep.

La salida es si se puede construir un asentamiento.

Sin golf

a -> {
    int
        h,
        f[] = new int[5],
        i = 0
    ;
    for (int x : a)
        f[x]++;
    for (h = f[4] / 4; i < 4; )
        h += --f[i] >> 31 | f[i++] / 4;
    return ~h < 0;
}

Explicación

hes el número de cuádruples de recursos disponibles para comerciar. Realizamos iteraciones sobre cada tipo de recurso (excepto Mineral), incrementando hpor cada cuádruple de recursos adicionales que tenemos, y disminuyendo donde no hay recursos presentes. Entonces nuestro resultado es si hes no negativo.

La línea

h += --f[i] >> 31 | f[i++] / 4;

se ajusta hadecuadamente independientemente de si no hay recursos (escasez) o si hay al menos un recurso (excedente). f[i]se decrementa para tener en cuenta el recurso requerido en el caso de excedente, produciendo -1 en el caso de escasez. El desplazamiento a la derecha con signo reduce la expresión a 0 (caso excedente) o -1 (caso de escasez), de modo que un OR bit a bit con el número f[i++] / 4de cuádruples excedentes (en el caso excedente) no tiene ningún efecto en el caso de escasez, pero da como resultado el número en sí mismo en el caso excedente.

Expresiones de gratitud

  • -9 bytes gracias a Nevay, maestro de bits
Jakob
fuente
-3 bytes: ...for(h=f[4]/4;i<4;h+=f[i++]/4)n+=--f[i]>>-1;return~h<n;.
Nevay
103 bytes:a->{int h,f[]=new int[5],i=0;for(int x:a)f[x]++;for(h=f[4]/4;i<4;h+=f[i++]/4)h+=--f[i]>>-1;return~h<0;}
Nevay
2
101 bytes:a->{int h,f[]=new int[5],i=0;for(int x:a)f[x]++;for(h=f[4]/4;i<4;)h+=--f[i]>>-1|f[i++]/4;return~h<0;}
Nevay
Ahora que es un poco de piratería jugosa!
Jakob
4

Retina , 34 bytes

^
BBBLLLWWWSSS
O`.
((.)\2{3}.*){4}

Pruébalo en línea! Explicación: la creación de una solución requiere 4 recursos, que son sus primeros B, L, W o S, o cualquier otro recurso 4 del mismo tipo. Esto es equivalente a agregar tres de cada uno de esos cuatro tipos de recursos, y luego contar para ver si tiene cuatro conjuntos de cuatro.

Neil
fuente
3

Jalea , 23 bytes

œ-4R¤©Ġs€4ẎL€>3+®e€$S>3

Pruébalo en línea!

Consulte la siguiente tabla para conocer los valores:

B: 1
L: 2
O: 5
W: 3
S: 4
Erik el Outgolfer
fuente
2

Python 3 , 79 78 bytes

Editar: -1 byte gracias a @ Mr.Xcoder

lambda x:3<sum((a>0)+~-a*(a>1)//4for a in map(x.count,"BLSW"))+x.count("O")//4

Pruébalo en línea!

Halvard Hummel
fuente
Si está dispuesto a cambiar a Python 2, puede hacerlo en 77 bytes
Sr. Xcoder
78 en Py 3 , o 76 en Py 2
Mr. Xcoder
@Señor. Xcoder ¿Por qué no haces una solución Python 2?
Jakob
@Jakob Porque es demasiado similar al de Halvard.
Sr. Xcoder
@ Mr.Xcoder lo mantendrá Python 3
Halvard Hummel
2

MATL , 19 bytes

Oh!5:=s4&\w4:)ghs3>

La entrada es un vector de fila numérico donde las letras se representan como números de la siguiente manera:

B: 1
L: 2
W: 3
S: 4
O: 5

La salida es 1para la verdad, 0para la falsedad.

¡Pruébelo en línea !: verifique todos los casos de prueba .

Cómo funciona

  1. Cuente las ocurrencias de cada recurso.
  2. Div-mod por 4.
  3. Cuente cuántos de los restantes para los primeros cuatro recursos (letras BLWS) no son cero. Esto le da un número c .
  4. Suma los cocientes. Esto le da un número s .
  5. Salida si c + s ≥ 4.

Código comentado

Oh     % Append 0 to implicit input. This is just in case inpout is empty
!      % Convert into column vector
5:     % Push row vector [1 2 3 4 5]
=      % Compare for equality, element-wise with broadcast
s      % Sum of each column. Gives number of times that each entry of
       % [1 2 3 4 5] appears in the input
4&\    % Mod-div 4, element-wise. Pushes vector of remainders and then vector
       % of quotients of division by 4
w      % Swap. Brings remainders to top
4:)    % Get the first four entries
g      % Convert to logical. This transforms non-zero values into 1
h      % Concatenate with vector of quotients
s      % Sum
3>     % Does the result exceed 3? Implicitly display
Luis Mendo
fuente
2

> <> , 61 bytes

510ap\~1(n;
1+$ap> i:0(?v8%:ag
0:ga:v?=5:+1<$-}$,4-%4:-}-${:)

Pruébalo en línea!

Utiliza la siguiente asignación de recursos:

O -> 0
B -> 1
L -> 2
W -> 3
S -> 4

Realmente no importa lo que la cartografía se utiliza, siempre y cuando estén en el rango 0-4, y 0se utiliza para O. hace uso del hecho de que la búsqueda de la combinación BLWSes la misma que en busca de la combinación OBLWS, mientras que ya tienen una Oen mano.

Sok
fuente
1

05AB1E , 19 bytes

0 -> Mineral
1 -> Ladrillo
2 -> Registro
3 -> Trigo
4 -> Oveja

Devuelve 0 cuando es falso y 1 en caso contrario.

{γvyDĀi¼¨}g4÷}¾)O3›

Pruébalo en línea!

Explicación:

{γvyDĀi¼¨}g4÷}¾)O3› Implicit input, e.g. 0030201
{                   Sort -> 0000123
 γ                  Split into chunks of consecutive elements: [0000, 1, 2, 3]
  vy                For each chunk...
    DĀ                 ...is different than 0?
      i¼¨}                ...if true: increment the counter by 1, and 
                              remove 1 element from the chunk
          g4÷         ...divide the number of elements by 4
             }      End For
              ¾     Push the counter
               )    Wrap the entire stack in a list
                O   Sum of that list
                 3> True if > 3
                    Implicit output

Solución no competitiva: 17 bytes

Hubo un error en 05AB1E cuando presenté por primera vez esa solución, donde algunos operadores manejaban mal las entradas vacías. Esto dio como resultado que esta solución respondiera 1con una entrada vacía. Esto ya se ha solucionado, por lo que esta solución funciona bien.

La diferencia aquí es que agregamos un mineral antes de eliminar uno de cada recurso, indiscriminadamente, contando la cantidad de recursos eliminados de esa manera. Luego disminuimos el contador en 1 para obtener el número correcto de B, L, W y S.

0«{γε¨g4÷¼}O¾<+3›

Pruébalo en línea!

scottinet
fuente
0

JavaScript (SpiderMonkey) , 116 bytes

s=>Array.from("BLOWS").reduce((m,c)=>Math.floor(((s+"BLSW".repeat(3)).match(new RegExp(c,'g'))||"").length/4)+m,0)>3

Pruébalo en línea!

Súper torpe mala respuesta. Estoy seguro de que podría limpiarse más. Método inspirado en la respuesta de Lynn en este hilo.

Pureferret
fuente
0

Kotlin , 131 129 bytes

Sumisión

fun r(i:String):Any=i.split("").groupingBy{it}.eachCount().map{when(it.key){
""->0
"O"->it.value/4
else->(it.value+3)/4}}.sum()>3

Prueba

fun r(i:String):Any=i.split("").groupingBy{it}.eachCount().map{when(it.key){
""->0
"O"->it.value/4
else->(it.value+3)/4}}.sum()>3

data class TestData(val input:String, val output:Boolean) {
    fun run() {
        val out = r(input)
        if (out != output) {
            throw AssertionError("Failed test: ${this} -> $out")
        }
    }
}
fun main(args: Array<String>) {
    listOf(

            TestData("BLWS", true),
            TestData("OOOOWLB", true),
            TestData("OOW", false),
            TestData("BBBO", false),
            TestData("", false),
            TestData("BBBBLW", false),
            TestData("BBBBBLW", true),
            TestData("OOOOOOOOOOOOOOOO", true),
            TestData("BLBLBLBLBL", true),
            TestData("BLSWBLSWBLSW", true)
    ).forEach(TestData::run)
    println("Test passed")
}

No puede funcionar en TryItOnline, pero funciona en try.kotlinlang.org

jrtapsell
fuente