Contador de contador


18

Na tipografia, um contador é a área de uma letra que é total ou parcialmente delimitada por uma forma de letra ou um símbolo. Um contador fechado é um contador totalmente fechado por uma forma de letra ou símbolo. Você deve escrever um programa que utiliza uma string como entrada e imprime o número total de contadores fechados no texto.

Sua entrada:

  • Pode ser uma entrada de linha de comando ou de STDIN, mas você deve especificar qual.

  • Consistirá inteiramente dos caracteres ASCII imprimíveis, significando todos os valores ASCII entre 32 e 126, inclusive. Isso inclui espaços. Mais Informações.

Agora, isso varia um pouco entre as fontes. Por exemplo, a fonte em que você está lendo isso considera 'g' como um contador fechado, enquanto a fonte do google possui 'g' com dois contadores fechados. Para que isso não ocorra, aqui está o número oficial de contadores fechados por personagem.

Todos os símbolos sem contadores fechados:

 !"'()*+,-./12357:;<=>?CEFGHIJKLMNSTUVWXYZ[\]^_`cfhijklmnrstuvwxyz{|}~

Observe que isso inclui espaço.

Aqui estão todos os símbolos com um contador fechado:

#0469@ADOPQRabdegopq

E aqui estão todos os símbolos com 2 contadores fechados:

$%&8B

E por último mas não menos importante, aqui estão algumas amostras de entradas e saídas.

Programming Puzzles and Code-Golf deve imprimir 13

4 8 15 16 23 42 deve imprimir 5

All your base are belong to us deve imprimir 12

Standard loopholes apply deve imprimir 12

Shortest answer in bytes is the winner! deve imprimir 8


1
Duas respostas enviaram funções em vez de programas completos. Embora isso seja permitido por padrão, suas palavras sugerem o contrário. Você poderia esclarecer?
Dennis

Você se importaria em revelar quais eram as contagens?
Martin Ender

3
Nenhuma das fontes em que estou visualizando a pergunta corresponde às contagens que você forneceu. Por exemplo, no navegador, o zero possui uma barra diagonal, dando dois contadores. A fonte no aplicativo Android não funciona, mas aqui ghá dois balcões fechados. Você determinou os contadores com base em qualquer fonte específica?
Martin Ender

1
@DJMcMayhem 'g' tem 1; embora esteja listado no código, gtenha 2. Um pouco confuso para ler, mas não acho que seja diferente por local.
OJFord 21/06

1
Não 0possui 2 contadores fechados em determinadas fontes, especialmente em muitas fontes monoespaçadas?
vsz 22/06/2015

Respostas:


10

Pitão, 31 bytes

sm@tjC"cúÁ-ÈN%³rØ|­"3Cdz

Demonstração.

Observe que o código pode não ser exibido corretamente devido ao uso de caracteres não ASCII. O código correto está no link.

Fiz uma tabela de pesquisa da saída desejada para cada caractere de entrada, girei-a em 32 para fazer uso da indexação modular de Pyth, colei um 1 no início e o interpretei como um número base 3, fornecendo o número 2229617581140564569750295263480330834137283757. Em seguida, converti esse número na base 256 e o ​​converti em uma string, que é a string usada na resposta.


29

Python 3, 63

print(sum(map(input().count,"#0469@ADOPQRabdegopq$%&8B$%&8B")))

Uma abordagem direta. Repete cada caractere com um contador fechado, somando o número de ocorrências, fazendo isso duas vezes para caracteres com dois contadores fechados. Seria o mesmo comprimento para escrever

"#0469@ADOPQRabdegopq"+"$%&8B"*2

Python 3 é necessário para evitar raw_input.


12

CJam, 41 39 37 34 bytes

"$%&8Badopq#0469@Rbeg"_A<eu+qfe=1b

Graças a @ jimmy23013 por jogar fora 3 bytes!

Experimente online.

Como funciona

"$%&8Badopq#0469@Rbeg"             e# Push that string.
                      _A<          e# Retrieve the first 10 characters.
                         eu+       e# Convert to uppercase and append.
                                   e# This pushes "$%&8Badopq#0469@Rbeg$%&8BADOPQ".
                            q      e# Read from STDIN.
                             fe=   e# Count the occurrences of each character. 
                                1b e# Base 1 conversion (sum).

2
"$%&8Badopq#0469@Rbeg"_A<eu+.
jimmy23013

@ jimmy23013: Eu tentei algumas variações de eue el, mas nunca achei isso. Obrigado!
Dennis

8

sed, 51

Com a ajuda do golfe de @manatwork e @TobySpeight:

s/[$%&8B]/oo/g
s/[^#0469@ADOPQRabdegopq]//g
s/./1/g

Entrada de STDIN. Com essa meta-pergunta em mente , a saída é unária:

$ echo 'Programming Puzzles and Code-Golf
4 8 15 16 23 42
All your base are belong to us
Standard loopholes apply
Shortest answer in bytes is the winner!' | sed -f countercounter.sed
1111111111111
11111
111111111111
111111111111
11111111
$ 

7

Perl, 41

$_=y/#0469@ADOPQRabdegopq//+y/$%&8B//*2

41caracteres +1 para a -pbandeira.

Isso usa y /// para contar os caracteres.

echo 'Programming Puzzles and Code-Golf' | perl -pe'$_=y/#0469@ADOPQRabdegopq//+y/$%&8B//*2'

6

APL GNU, 39 bytes

+/⌈20÷⍨26-'$%&8B#0469@ADOPQRabdegopq'⍳⍞

Experimente online no GNU APL.js .

Como funciona

                                      ⍞ Read input.
          '$%&8B#0469@ADOPQRabdegopq'⍳  Compute the indexes of the input characters
                                        in this string. Indexes are 1-based.
                                        26 == 'not found'
       26-                              Subtract each index from 26.
   20÷⍨                                 Divide those differences by 20.
  ⌈                                     Round up to the nearest integer.
+/                                      Add the results.

6

JavaScript, 86

E / S via pop-up. Execute o trecho em qualquer d recente navegador para teste.

for(c of prompt(t=0))c='$%&8B#0469@ADOPQRabdegopq'.indexOf(c),~c?t+=1+(c<5):0;alert(t)


6

K, 54 43 42 37 bytes

+//(30#"$%&8B#0469@ADOPQRabdegopq"=)'

Corte 5 bytes graças a @JohnE!

Versão antiga:

f:+/(#&"#0469@ADOPQRabdegopq$%&8B$%&8B"=)'

Original:

f:+/{2-(5="$%&8B"?x;20="#0469@ADOPQRabdegopq"?x;0)?0}'

O #&interior das parênteses poderia ser tão facilmente +/, o que significa que você poderia ir mais longe +//"#0469@ADOPQRabdegopq$%&8B$%&8B"=\:. Finalmente, não é necessário ter o f:dado que a função pode ser usada na forma tácita. Isso reduziria você a 38!
Johne

Infelizmente o truque algumas outras soluções têm utilizado para compactar a tabela de pesquisa sai morto mesmo com a solução de 38 byte atual: +//(30#"$%&8B#0469@ADOPQRabdegopq")=\:. Isso pode ser o melhor que podemos fazer.
Johne

haha, assim que eu +//(30#"$%&8B#0469@ADOPQRabdegopq"=)'
postei

5

C, 127 bytes

n;f(char*i){char*o="#0469@ADOPQRabdegopq",*t="$%&8B";for(;*i;i++)if(strchr(o,*i))n++;else if(strchr(t,*i))n+=2;printf("%d",n);}

Bem direto. Versão não destruída:

int num = 0;
void f(char* input)
{
    char *one="#0469@ADOPQRabdegopq";
    char *two="$%&8B";

    for(;*input;input++)
        if(strchr(one, *input))     //If current character is found in first array
            num ++;
        else if(strchr(two, *input))//If cuurent character is found in second array
            num += 2;

    printf("%d", num);
}

Teste-o aqui

Se argumentos de função não forem permitidos, a stdinversão ocupará até 141 bytes:

n;f(){char*o="#0469@ADOPQRabdegopq",*t="$%&8B",i[99],*p;gets(i);for(p=i;*p;p++)if(strchr(o,*p))n++;else if(strchr(t,*p))n+=2;printf("%d",n);}

Observe que a versão acima pressupõe que a entrada tenha no máximo 98 caracteres.

Teste aqui

Versão dos argumentos da linha de comando (143 bytes):

n;main(c,v)char**v;{char*o="#0469@ADOPQRabdegopq",*t="$%&8B",*p=v[1];for(;*p;p++)if(strchr(o,*p))n++;else if(strchr(t,*p))n+=2;printf("%d",n);}

Teste aqui


1
@DJMcMayhem C realmente não é tão ruim assim. Tente jogar golfe em Fortran 77.;)
Alex A.

5

Python 2, 96 90 75 67 + 2 = 69 bytes

Não consigo pensar em outra maneira de fazer isso ... é o que eu pensaria até ver a solução do xnor. Vou postar o que eu tinha de qualquer maneira.

Agradecimentos a FryAmTheEggman por salvar 6 bytes

Tudo bem, agora estou feliz com isso.

Obrigado ao xnor pelo truque de busca, economizando 4 bytes.

Adicionado dois bytes, pois a entrada precisa estar entre aspas.

print sum('#0469@ADOPQRabdegopq$%&8B'.find(x)/20+1for x in input())

1
Eu gosto do uso inteligente de índices! Além disso, o python 3 é um pouco menor porque usa entrada em vez de raw_input.
DJMcMayhem


Ah eu vejo. Desculpe, eu combinei com o comentário Python 3 do @ DJMcMayhem.
manatwork

4

Java, 162

class C{public static void main(String[]a){System.out.print(-a[0].length()+a[0].replaceAll("[#0469@ADOPQRabdegopq]","..").replaceAll("[$%&8B]","...").length());}}

Bem, se tiver que ser um programa completo ... É apenas uma linha que combina caracteres e os substitui por uma string mais longa. Em seguida, retorna a diferença de comprimento do original. Infelizmente, o java realmente não tem nada para contar apenas o número de correspondências.

Aqui está com quebras de linha:

class C{
    public static void main(String[]a){
        System.out.print(
                -a[0].length() +
                a[0].replaceAll("[#0469@ADOPQRabdegopq]","..")
                .replaceAll("[$%&8B]","...")
                .length()
                        );
    }
}


4

Javascript, 114 95 bytes

alert(prompt().replace(/[#046@ADOPQRabdegopq]/g,9).replace(/[$%&8B]/g,99).match‌​(/9/g).length)

Agradeço a Ismael Miguel por me ajudar a jogar isso.


2
93 bytes:alert(prompt().replace(/[#046@ADOPQRabdegopq]/g,9).replace(/[$%&8B]/g,99).match(/9/g).length)
Ismael Miguel

Desculpe por contar mal. Sim, é 95.
Ismael Miguel

3

Ruby, 59 bytes

a=gets;p a.count('#0469@ADOPQRabdegopq')+2*a.count('$%&8B')

Entrada da linha de comando ou stdin. Até agora, o mais curto, usando uma linguagem não esotérica.

Atualização: chilemagic beat me


3

Retina , 44 bytes

1

[#0469@ADOPQRabdegopq]
1
[$%&8B]
11
[^1]
<empty line>

Dá saída em unário.

Cada linha deve ir para seu próprio arquivo ou você pode usar o -ssinalizador Por exemplo:

> echo "pp&cg"|retina -s counter
11111

Os pares de linhas (pares substituto de padrão) executam as seguintes etapas de substituição:

  • Remover 1's
  • Substitua letras com 1 contador por 1
  • Substitua as letras de 2 contadores por 11
  • Remover tudo, mas os 1's

3

J, 43

Como uma função:

   f=:[:+/[:,30$'$%&8B#0469@ADOPQRabdegopq'=/]
   f 'text goes here'
6

46 bytes (linha de comando)

Como um programa de linha de comando independente:

echo+/,30$'$%&8B#0469@ADOPQRabdegopq'=/>{:ARGV

Salve a linha acima como counter2.ijse chame na linha de comando:

$ jconsole counter2.ijs 'Programming Puzzles and Code Golf'
13

Não é permitido copiar e colar a entrada no código, mas uma função que pode receber a entrada como argumento está ok. Por exemplo f=:your_function_code.
randomra

2

Julia, 77 74 bytes

t=readline();length(join(t∩"#0469@ADOPQRabdegopq")*join(t∩"\$%&8B")^2)

Isso lê o texto de STDIN e imprime o resultado em STDOUT.

Ungolfed + explicação:

# Read text from STDIN
t = readline()

# Print (implied) to STDOUT the length of the intersection of t with the
# 1-closed counter list joined with the duplicated intersection of t with
# the 2-closed counter list
length(join(t ∩ "#0469@ADOPQRabdegopq") * join(t ∩ "\$%&8B")^2)

Exemplo:

julia> t=readline();length(join(t∩"#0469@ADOPQRabdegopq")*join(t∩"\$%&8B")^2)
Programming Puzzles and Code Golf
13


2

GNU APL, 37 caracteres

+/,⍞∘.=30⍴'$%&8B#0469@ADOPQRabdegopq'

construa um vetor de caractere que contenha caracteres de 2 contadores duas vezes (30⍴)

compare cada caractere de entrada com cada caractere do vetor (∘. =)

resumir partidas sorteadas (+ /,)


1

Javascript 159 , 130 bytes

function c(b){return b.split("").map(function(a){return-1!="$%&8B".indexOf(a)?2:-1!="#0469@ADOPQRabdegopq".indexOf(a)?1:0}).reduce(function(a,b){return a+b})};

não minificado:

function c(b) {
    return b.split("").map(function(a) {
        return -1 != "$%&8B".indexOf(a) ? 2 : -1 != "#0469@ADOPQRabdegopq".indexOf(a) ? 1 : 0
    }).reduce(function(a, b) {
        return a + b
    })
};

Com a ajuda do @ edc65:

function c(b){return b.split('').reduce(function(t,a){return t+(~"$%&8B".indexOf(a)?2:~"#0469@ADOPQRabdegopq".indexOf(a)?1:0)},0)}

2
Como ~ -1 == 0, você pode escrever em ~x?vez de -1 != x?. Veja-me responder para um exemplo de uso.
edc65

2
function c(b){return b.split('').reduce(function(t,a){return t+(~"$%&8B".indexOf(a)?2:~"#0469@ADOPQRabdegopq".indexOf(a)?1:0)},0)}Não há necessidade de ter mapem seguidareduce
edc65

1

Haskell, 117

a="#0469@ADOPQRabdegopq"
b="$%&8B"
c n[]=n
c n(x:s)
 |e a=f 1
 |e b=f 2
 |True=f 0
 where
 e y=x`elem`y
 f y=c(n+y)s

c é uma função c :: Int -> String -> Int que pega um contador e uma string e percorre a string uma letra de cada vez, verificando se a letra atual é um membro da matriz de 1 ponto ou da matriz de 2 pontos e se chama para o restante da cadeia após incrementar o contador a quantidade apropriada.

Chamada com contador = 0 em ghci:

ghci> c 0 "All your base are belong to us"
12

1

C #, 157

void Main(string s){int v=0;v=s.ToCharArray().Count(c=>{return "#0469@ADOPQRabdegopq".Contains(c)||"$%&8B".Contains(c)?++v is int:false;});Console.Write(v);}

Ungolfed:

void Main(string s)
{
    int v = 0;

    v = s.ToCharArray()
    .Count(c => 
    {
        return "#0469@ADOPQRabdegopq".Contains(c) || "$%&8B".Contains(c) ? ++v is int:false;
    });

    Console.Write(v);
}

Convertendo a cadeia de caracteres em uma matriz de caracteres e ver se cada caracter está em um dos contadores. Se estiver no segundo, apenas o incremento do contador novamente.


1

Erlang, 103 bytes

Este é um programa completo que é executado usando escript. A primeira linha do arquivo deve estar em branco (adicionando 1 byte).

main([L])->io:write(c(L,"#0469@ADOPQRabdegopq")+2*c(L,"$%&8B")).
c(L,S)->length([X||X<-L,S--[X]/=S]).

Exemplo de execução:

$ escript closed.erl 'Shortest answer in bytes is the winner!'
8$

Bem-vindo ao PPCG, c (L, "# 0469 @ ADOPQRabdegopq") + 2 * c (L, "$% e 8B") é maior que c (L, "# 0469 @ ADOPQRabdegopq $% & 8B $% & 8B") por 5 bytes :).
precisa

@ Katyenko, obrigado pela sugestão. Lamentavelmente, ele não funciona corretamente para determinadas entradas. "$% & 8B" conta com 5, mas deve ser 10. A função c / 2 funciona filtrando os caracteres da string que não pertencem a um conjunto de caracteres, como "$% & 8B". Ele verifica a inclusão do conjunto excluindo o caractere a ser testado do conjunto e comparando o resultado com o conjunto original. Se eles não forem iguais, o caractere estava no conjunto e está incluído. Várias cópias de caracteres no conjunto não têm efeito.
Edwin Fine

Entendo, não sei erlang, estava pensando que você estava usando uma corda para contar o contador: 3. De qualquer forma, deixa pra lá, e bem feito :) #
23415

0

C, 99 bytes

n;f(char*i){for(char*o="#0469@ADOPQRabdegopq$%&8B",*t=o+20;*i;)n+=2-!strchr(o,*i)-!strchr(t,*i++);}

Explicação

Joguei ainda mais a resposta de Cool Guy ; demorou muito para ser um comentário. Em vez do if/ else, aproveitei a !conversão de um ponteiro para bool. Eu também fiz oincluir tpara que eu pudesse adicionar "está dentro o" e "está dentrot " para o número total de contadores.

Código expandido

#include <string.h>
int num = 0;

void f(char* input)
{
    char *one = "#0469@ADOPQRabdegopq"  "$%&8B";
    char *two = strchr(one, '$');

    while (*input) {
        num += 2 - !strchr(one, *input) - !strchr(two, *input));
        ++input;
    }
}

A saída está em num , que deve ser limpa antes de cada chamada.

Programa de teste e resultados

#include <stdio.h>
int main() {
    const char* a[] = {
        "Programming Puzzles and Code-Golf",
        "4 8 15 16 23 42",
        "All your base are belong to us",
        "Standard loopholes apply",
        "Shortest answer in bytes is the winner!",
        NULL
    };
    for (const char** p = a;  *p;  ++p) {
        n=0;f(*p);
        printf("%3d: %s\n", n, *p);
    }
    return 0;
}
 13: Programming Puzzles and Code-Golf
  5: 4 8 15 16 23 42
 12: All your base are belong to us
 12: Standard loopholes apply
  8: Shortest answer in bytes is the winner!
 37: n;f(char*i){for(char*o="#0469@ADOPQRabdegopq$%&8B",*t=o+20;*i;)n+=2-!strchr(o,*i)-!strchr(t,*i++);}

O código em si contém 37 contadores por sua própria métrica.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.