Posso me acalmar?

23

No jogo de tabuleiro The Settlers of Catan , existem cinco tipos de recursos: Brick, Log, Ore, Wheat e Sheep. Construir um assentamento custa um tijolo, um tronco, um trigo e uma ovelha. No entanto, você também pode trocar quatro recursos idênticos para obter um recurso de um tipo diferente. Por exemplo, se você tivesse quatro minérios na mão, poderia trocá-los e obter uma ovelha.

Seu trabalho é determinar se posso ou não construir um acordo, dada a minha mão.

Sua tarefa

Entrada será uma seqüência de letras B, L, O, W, e S, tomado em qualquer formato razoável. Essas letras correspondem aos cinco tipos de recursos fornecidos acima. Você deve saber se tenho ou não os recursos necessários para construir um acordo, levando em consideração a possibilidade de negociar quatro do mesmo tipo.

Isso é , então o código mais curto em bytes vence.

Notas

  • Você não precisa exibir quais negociações eu preciso realizar ou quantos acordos eu poderia construir. Um simples "sim" ou "não" serve.
  • Você não pode assumir que a entrada está em qualquer ordem específica. Em particular, você não pode supor que os recursos do mesmo tipo estejam agrupados, assim OBLSOcomo uma entrada válida.
  • Esse é ; portanto, você pode usar qualquer valor que queira que signifique "sim" e "não", desde que os dois valores escolhidos sejam distintos e consistentes.
  • As únicas regras com as quais estamos preocupados aqui são as listadas acima. Regras mais complicadas de Colonos de Catan, como negociar com outros jogadores ou em portos, não são relevantes aqui.
  • Os caracteres de entrada ( B, L, O, W, S) pode ser substituído por outros valores se é mais fácil para o seu idioma específico de escolha, desde que há cinco entradas distintas. Se você usar outros valores de entrada, especifique-os na sua resposta.

Exemplos

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
fonte
13
"Construir um assentamento custa um tijolo, um tronco, um trigo e uma ovelha". Sim, para realizar o ritual de construir um assentamento, você precisa de uma ovelha. Me pergunto por que não existem vegetarianos?
Okx
5
@ Ok, a ovelha dá o leite que acompanha o pão do trigo para alimentar os construtores enquanto eles constroem (eles levam as ovelhas no final como pagamento). Nenhum animal foi ferido no edifício do assentamento
Aganju
Tudo bem que o programa exija que a entrada seja classificada?
NieDzejkob 5/09
@NieDzejkob Não, exigir um pedido é especificamente proibido. Seu programa deve estar preparado para lidar com qualquer sequência dos cinco recursos.
Silvio Mayolo 5/09
@SilvioMayolo desculpe, eu não sei como eu perdi isso
NieDzejkob

Respostas:

16

Python 2 , 54 bytes

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

Experimente online!

Para cada um de nossos recursos, contamos o número de "liberdades" dadas por ter n desse recurso. A liberdade representa uma oportunidade de preencher um dos espaços de tijolo-log-trigo-ovelha que precisamos preencher para resolver, respondendo pelo fato de que podemos converter nossos recursos.

Para todo o BLSW, ter um dos recursos nos dá uma liberdade, e todo excesso adicional de 4 nos dá outro. A regra da contagem da liberdade é assim:

* 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.
* 

Então n tijolos / toras / trigo / ovelha dão ⌊ (n + 3) / 4⌋ liberdades.

Para os minérios, apenas o excesso de quartetos conta. A regra da contagem da liberdade é assim:

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

Então n minérios dar ⌊n / 4⌋ liberdades.

Teorema: podemos resolver se, e somente se, tivermos ≥ 4 dessas "liberdades".

Então, contamos nossas liberdades e verificamos se existem ≥ 4 delas. Para lidar com a contagem de minérios como ⌊n / 4⌋ mas outros recursos ⌊ (n + 3) / 4⌋, aumentamos artificialmente as contagens dos outros recursos em 3 e depois contamos ⌊n / 4⌋ para todos eles. Fazemos isso mapeando em (s+"BLSW"*3).countvez de s.count.

Prova :

  • Suponha que possamos resolver. Então, para cada um de [B, L, S, W], (a) usamos 1 desse recurso que já possuíamos ou (b) sacrificamos 4 de algum outro recurso (incluindo minérios) para criá-lo. Nos dois casos, contamos pelo menos 1 liberdade pelas regras acima. Portanto, temos ≥ 4 liberdades.

  • Suponha que tenhamos 4 liberdades, k das quais são devidas a "excessos" (toda liberdade de minérios é um excesso, e toda liberdade de outros recursos além do primeiro também é) e 4-k são testemunhas de possuir pelo menos uma brick / log / wheat / sheep (aquele que deu a "primeira liberdade"). Em seguida, preenchemos 4-k slots com o tijolo / log / trigo / ovelha que nos deu nossa primeira liberdade e preenchemos os k slots restantes, convertendo nossos excessos. Todos os 4 slots estão preenchidos e podemos resolver. Obviamente, ainda podemos fazer isso se tivermos mais de quatro liberdades.

Essa prova é péssima, mas estou com sono. Tenho certeza de que há uma explicação melhor.

Lynn
fonte
2
Então, digamos sé OOOOBLW, você acaba ficando sum(n/4for n in map(("OOOOBLWBBBLLLSSSWWW").count,"BLSWO"))>3... por isso para cada um de BLOWSvocê contar quantas vezes ele aparece no essa seqüência inicial de "BLWS"*3, em seguida, resumir.
Pureferret 5/09/17
2
Precisamente! (A seqüência de caracteres é "OOOOBLWBLSWBLSWBLSW", na verdade, mas as contagens são os mesmos, é claro.)
Lynn
Ser um mapa em Python 'atrasado' sempre me confunde!
Pureferret 5/09/17
O espaço entre eles in"BLSWO"é desnecessário em Python, não é? Parece funcionar na TIO, pelo menos ..
Kevin Cruijssen
8

Python 2 ,  52  51 bytes

-1 byte graças a Luke (substitua >=0por <0, invertendo os False/ Trueresultados)

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

Uma função sem nome, utilizando uma sequência de caracteres B , O , W , L e S (como no OP) e retornando Falsese você puder resolver ou Truenão.

Experimente online! (coage a saída para oyes/nodo OP).

Quão?

Esta é uma porta da minha resposta Jelly. Precisamos compensar qualquer B , W , L ou S ausente do restante depois de usar um de cada um deles. Como tal, podemos adicionar um O extra à nossa mão, reduzir todas as contagens em um, depois dividir todas as contagens por quatro e depois somar - se o resultado for zero ou mais, podemos resolver (ou porque não havia recursos necessários ausentes) ou porque podemos negociar para adquirir o (s) desaparecido (s)).

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
fonte
Que tal usar Falsepara 'yes'e Truepara 'no'? Então você pode mudar >=para <, economizando 1 byte.
Luke
Prefiro sua escolha de ordenação de recursos à pergunta!
Neil
7

Pitão , 14 bytes

gsm/t/+Q4d4U5Z

Experimente aqui! ou Verifique todos os casos de teste.

Pitão ,  31 27 17  16 bytes

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

Verifique os casos de teste.

Como isso funciona?

Explicação 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.

Explicação 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.

Estes são os códigos usados ​​pelo meu programa:

B -> 0
L -> 1
S -> 2
W -> 3
O -> 4
Mr. Xcoder
fonte
+%ld4/ld4->s.Dld4
Erik the Outgolfer
Oh, tudo bem então.
Erik the Outgolfer
Eu acredito que //Q4 4pode ser /Q16, mas eu realmente não estou certo ...
Erik o Outgolfer
@EriktheOutgolfer Era inválido ... Falha BBBO, por exemplo
Sr. Xcoder 4/17/17
@EriktheOutgolfer Não, é contar as ocorrências 4e dividir por 4.
Mr. Xcoder
6

Geléia ,  13  12 bytes

;5ċЀ5’:4S>-

Um link monádico que aceita uma lista de números representando os recursos que você possui e que retorna 1se puder se estabelecer ou 0não.

Os recursos são 1, 2, 3, 4, 5onde 5representa Ore .

Experimente online! ou consulte a suíte de testes (usando o OP IO).

Quão?

A idéia é primeiro contar os recursos por tipo e, em seguida, reduzir todas as contagens de B , L , W e S em um - se não contarmos nenhum desses quatro, agora eles terão entradas de -1 - precisamos adquirir eles de nossos recursos restantes (na verdade, isso é obtido adicionando O ( 5) extra e reduzindo todas as cinco contagens em 1 ). Em seguida, dividimos por inteiro todos esses valores por quatro para ver quantas unidades podemos negociar com cada uma de nossas contagens restantes por tipo de recurso, sem afetar as contagens -1 e 0 (observe que -1 dividido por inteiro por quatro é-1 , não 0 ). Por fim, somamos os valores e verificamos se o resultado é maior ou igual a zero (aqui, maior que -1 pode ser usado, pois sempre temos números inteiros).

;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
fonte
5

Java 8, 101 bytes

Lambda de int[]até boolean. Atribuir 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;}

Experimente Online

Entrada e saída

A entrada é uma matriz de números inteiros de 0 a 4, inclusive. 4 representa o minério e os outros mapeamentos são imateriais. Meus casos de teste são traduções diretas daqueles em questão, com 0 como Brick, 1 como Log, 2 como Wheat e 3 como Sheep.

A saída é se um assentamento pode ser construído.

Ungolfed

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;
}

Explicação

hé o número de quádruplos de recursos disponíveis para negociação. Nós iteramos sobre cada tipo de recurso (exceto Ore), aumentando hpara cada quádruplo de recursos extras que temos e diminuindo onde nenhum recurso está presente. Então nosso resultado é se hnão é negativo.

A linha

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

ajusta hadequadamente, independentemente de não haver recursos (escassez) ou de pelo menos um recurso (excedente). f[i]é decrementado para contabilizar o recurso necessário no caso de superávit, produzindo -1 no caso de falta. O deslocamento à direita assinado reduz a expressão para 0 (caso excedente) ou -1 (caso excedente), de modo que um OR bit a bit com o número f[i++] / 4de quádruplos excedentes (no caso excedente) não tem efeito no caso escassez, mas resulta no número próprio caso excedente.

Agradecimentos

  • -9 bytes graças a Nevay, mestre de bits
Jakob
fonte
-3 bytes: ...for(h=f[4]/4;i<4;h+=f[i++]/4)n+=--f[i]>>-1;return~h<n;.
Nevay 04/09
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 4/17
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 04/04
Agora isso é um pouco de hacking!
Jakob
4

Retina , 34 bytes

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

Experimente online! Explicação: A construção de uma liquidação requer 4 recursos, que são seus primeiros B, L, W ou S ou quaisquer outros 4 recursos do mesmo tipo. Isso equivale a adicionar três de cada um desses quatro tipos de recursos e contar para ver se você tem quatro conjuntos de quatro.

Neil
fonte
3

Gelatina , 23 bytes

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

Experimente online!

Consulte a seguinte tabela para obter os valores:

B: 1
L: 2
O: 5
W: 3
S: 4
Erik, o Outgolfer
fonte
2

Retina , 43 bytes

O`.
O{4}
a
}`([^a])\1{4}
$1a
O

D`[^a]
.{4}

Experimente online!

fireflame241
fonte
2

Python 3 , 79 78 bytes

Edit: -1 byte graças a @ Mr.Xcoder

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

Experimente online!

Halvard Hummel
fonte
Se você estiver disposto a mudar para o Python 2, poderá fazê-lo em 77 bytes.
Sr. Xcoder 4/17/17
78 no Py 3 ou 76 no Py 2
Mr. Xcoder 4/17
@Sr. Xcoder Por que você não cria uma solução Python 2?
Jakob
@ Jakob Porque é muito parecido com o de Halvard.
Sr. Xcoder 4/17/17
@ Mr.Xcoder o manterá em Python 3
Halvard Hummel
2

MATL , 19 bytes

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

Entrada é um vetor de linha numérica em que as letras são representadas como números da seguinte maneira:

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

A saída é 1para verdade, 0para falsidade.

Experimente online !: verifique todos os casos de teste .

Como funciona

  1. Contar ocorrências de cada recurso.
  2. Div-modifique-os por 4.
  3. Conte quantos dos restantes quatro primeiros recursos (letras BLWS) são diferentes de zero. Isso fornece um número c .
  4. Soma os quocientes. Isso fornece um número s .
  5. Saída se 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
fonte
2

> <> , 61 bytes

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

Experimente online!

Usa o seguinte mapeamento de recursos:

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

Realmente não importa o que o mapeamento é usado, contanto que eles estão na faixa 0-4, e 0é usado para O. faz uso do fato de que procura a combinação BLWSé o mesmo que olhar para a combinação OBLWSenquanto já tendo um Oem mão.

Sok
fonte
1

05AB1E , 19 bytes

0 -> Minério
1 -> Tijolo
2 -> Log
3 -> Trigo
4 -> Ovelha

Retorna 0 quando falso e 1 caso contrário.

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

Experimente online!

Explicação:

{γ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

Solução não competitiva: 17 bytes

Houve um erro no 05AB1E quando enviei a solução pela primeira vez, em que alguns operadores lidaram mal com entradas vazias. Isso resultou nessa solução respondendo 1a uma entrada vazia. Agora isso foi corrigido, portanto, esta solução funciona perfeitamente.

A diferença aqui é que adicionamos um minério antes de remover um de cada recurso, indiscriminadamente, contando o número de recursos removidos dessa maneira. Em seguida, decrementamos o contador em 1 para obter o número correto de B, L, W e S.

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

Experimente online!

escoteiro
fonte
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

Experimente online!

Super má resposta desajeitada. Tenho certeza de que poderia ser limpo mais. Método inspirado na resposta de Lynn neste tópico.

Pureferret
fonte
0

Kotlin , 131 129 bytes

Submissão

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

Teste

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")
}

Não pode funcionar no TryItOnline, mas funciona no try.kotlinlang.org

jrtapsell
fonte