Esta competição acabou.
O vencedor é CJam com 22 caracteres, superando a resposta de TwiNight por um caractere. Parabéns Dennis !
Uma menção honrosa vai para Falko , que ficou totalmente doida com as importações gratuitas.
.
Há um tempo atrás, eu queria saber como posso superar os smartphones modernos com o meu Nokia 3310 e, embora algumas respostas sejam realmente boas, ainda não consigo acompanhar! Talvez eu deva adotar uma abordagem diferente e simplesmente não escrever nenhuma palavra que seja difícil de digitar.
Chamaremos um pedaço de texto de fácil digitação se não houver duas letras consecutivas no mesmo botão do teclado do telefone, de acordo com o layout padrão:
Sua tarefa
Sua tarefa é escrever um programa / função que aceite uma string s
de stdin / como parâmetro e retorne um valor verdadeiro, se s
for facilmente digitável, e um valor falso, caso contrário. A entrada consistirá apenas de letras minúsculas e espaços e é garantida que não está vazia!
Pontuação
Este é um codegolf, então a menor contagem de caracteres vence.
Declarações de importação não serão contados para a sua pontuação final, por isso, se você sempre quis para uso std::set_symmetric_difference
, liftM4
ou itertools.combinations
em seu código, agora é a hora!
-3 se o seu código-fonte for facilmente digitado, assumindo que tudo o que não é uma letra está no botão 0. Afinal, talvez eu queira enviar seu código para alguns amigos!
Casos de teste
Aqui estão alguns casos de teste para verificar se seu código está funcionando como pretendido:
"x" -> True
"aardvark" -> False
"ardvark" -> True
"flonk" -> False
"im codegolfing all day long" -> False
"i indulge in minimizing bytecount" -> True
"havent heard from you in a long time" -> False
"your silence was of undue permanence" -> True
"how are you" -> False
"how are you" -> True
Feliz golfe!
Respostas:
CJam,
34312722 caracteresExperimente online.
Exemplo de execução
Como funciona
fundo
O núcleo do código consiste em aplicar um mapa F a cada caractere C da sequência de entrada, para que as imagens dos símbolos na mesma tecla sejam correspondentes. Encontrei o mapa adequado observando o seguinte:
O mapa T: C ↦ (C - 'h') + 13 transforma a sequência S: = "abcdefghijklmnopqrstuvxyz" da seguinte maneira:
Para as chaves 0para 6, seria suficiente para dividir T (C) por 3 , mas nós temos que aplicar algum tipo de correção para os personagens s , t , v , y e z .
O mapa D: C ↦ (C - 'h') / 9 transforma a cadeia S na seguinte matriz:
Isto corrige os quocientes de s , t , v , y e z , sem afectar os outros.
Finalmente, o mapa F: C ↦ (T (C) - D (C)) / 3 transforma a sequência S da seguinte maneira:
Tudo o que resta é comparar os caracteres consecutivos de alguma forma. Para esse propósito, XOR F (C) com a imagem do caractere anterior - para o primeiro, XOR F (C) com 1 (valor padrão da variável X ), que não possui pré-imagem - e multiplicamos todos os resultados.
O produto será Falsas se e apenas se um dos factores é zero, ou seja, se e somente se dois caracteres consecutivos têm a mesma imagem por F .
fonte
Python
2-80, 68, 64, 61, 58, 50, 48, 45, 4442Embora esteja ficando um pouco ridículo agora, continuarei usando importações de bibliotecas gratuitas, até a
__builtin__
biblioteca:Portanto, apenas a seguinte linha curta conta para o comprimento do código:
Créditos à Markuz pelas idéias a respeito
input()
! Esses desafios de importação gratuita sempre apresentam algumas bibliotecas menos conhecidas. ;)Alternativa usando apenas a
operator
biblioteca (98, 8379):Eu vou parar por aqui Mas você poderia promover golf esta versão usando
sys
,pprint
e outras bibliotecas ...Alternativa sem bibliotecas (105):
fonte
ord(c)
a uma variável (digamoso
) e subtraindoc/112
e, emc/119
vez dos booleanos?lambda
expressões tão facilmente. Com[(o-1-o/112-o/119)/3for o in map(ord,s)]
eu termino com 80 bytes novamente.from sys import argv as s
usando, ems[1]
vez de #input()
input
de__builtin__
bem é, na verdade ainda melhor: D salvando ainda um outro Byte.RubyRegex (most popular flavours),10683 bytesBecause regex
I've just cut the middleman (Ruby) and made this a pure-regex solution. Works in a lot of flavours and only finds a match if the string does not contain two consecutive characters on the same button.
fonte
{2}
outside the alternation, saving 22 bytes?Bash+coreutils, 49
Returns an exit code of 1 for TRUE and 0 for FALSE:
fonte
perl -pE'y/a-z/aaadddgggjjjmmmpppptttwwww/;$_=!/(.)\1/' <(echo "x")
It prints 1 for true and nothing for false.aaadddgggjjjmmmpppptttwwww
but I've given up.11122233344455566667778888
will do. By base 36 encoding the first 19 digits of this number, we can save 1 char!APL(Dyalog),
2423Explanation
⍞
: Takes string input from screen⎕AV
: This is the atomic vector which is bascially a string of all characters APL recognizes, which of course include all lowercase letters (index 18~43) and space (index 5)⍳
:IndexOf
function. For many functions in APL that takes one or two scalar arguments, you can feed it an array in place of a scalar - APL will do the looping for you. So⍳
returns a numeric array of indices..21-.31×
: Times 0.31 and then subtract from 0.21. This is a little trick that maps letter on the same key (especially PQRS) to the same number (when rounded down to integers), except Z, which get mapped to its own group¯13⌈
:max
with -13. This brings Z back to the group with WXY⌊
: Round down to integers2≠/
: Pairwise-≠
. Returns a boolean array for each consecutive pair.∧/
: AND together all entries of the resulting array.fonte
∧/2≠/
(all consecutive pairs are typed on different keys) instead of~∨/2=/
(no consecutive pair is typed on the same key.) APL FTW!!!Perl - 44
This is basically a Perl adaptation of @DigitalTrauma's answer posted with his permission. Shaved off 2 characters thanks to @KyleStrand.
43 characters + 1 for
-p
flag.y///
is the same astr///
. It prints1
for true and nothing for false. I can post a detailed explanation if requested.Example run:
Perl - 81
+1 for
-n
flag. It works by usingjoin
to create the regex (same one as Martin's), which shaves of a few bytes.Example run:
fonte
a
andz
remain untransliterated?y/b-y/aadddgggjjjmmmpppptttzzz/;$_=!/(.)\1/
Also, this won't handle spaces, will it?a
andz
remain the same. Updated answer!JavaScript -
159156 bytesReturns 1 for truthy and 0 for falsy.
If only I could get rid of the keywords.
fonte
function g(s){p=n=-1;for(i=0;i<s.length;i++){p=n;n=s.charCodeAt(i)-97;n>17&&n--;n>23&&n--;if(~p)continue;if(~(p/3)==~(n/3))return 0}return 1}
!=
in the for loop by a<
.c, 74 bytes
Returns a non-zero exit status for TRUE and 0 for FALSE:
fonte
while
tofor(;c=~getchar();d=c/3)
, and another byte by changing your firstif
to a?:
operator.c=getchar()
are required though because~
has higher precedence than=
. Still, I'll take the other two bytes :)exit(d!=c/3);
instead ofif(d==c/3)exit(0);
work?Ruby 1.8,
89838178 bytesHere is another submission. To my shame, it beats the regex. :(
This takes the string via command-line argument and prints a boolean.
As for the algorithm, I'm shifting down the letters after
p
by one and afterz
by two, and then I check that there are no collisions after integer division by 3.PS: This is the first time, that using Ruby 1.8 shortened the code (due to the shorter way to get character codes).
fonte
Cobra - 80
fonte
JavaScript (ES6) 66
74The inner loop find the group for each character. Conceptually is a 'reduce' but 'map' is shorter. The outer loop compare the group of consecutive chars and exits with false if they are equal.
Test In Firefox/Firebug console
Output
fonte
.some
instead of every. Because even if it fails one time, the answer is falsy.some
andevery
are interchangeble, fiddling with the conditions. But here simply putsome
instead ofevery
will not work, try it.[...s].every
trick in my golfs :)Perl, 83 bytes
Making heavy abuse of $_ in Perl.
fonte
-e
in Perl, is free.) 71 characters alternative with command-line parameters:perl -nlaF -e 'map{$_=ord;$_=($_-$_/112-$_/119-1)/3;die 0 if$l==$_;$l=$_}@F;die 1'
.-l
, but it looks good!-l
as replacement forchop
. But of course, you are right.Two tasks are tricky in Python; detecting chains, and assigning the groups. Both can be assisted using numpy, but it is not in the standard library.
Python 2 (only standard library) - 59 chars function
Python 2 (only standard library) - 53 chars stdin to exit value
Here I abuse the fact that
issubclass(bool,int)
, so changingall()
toany()
gets me a valid exit value, shaving off thenot()
from the return value. The removal of function overhead made the regex versions fall behind in size.fonte
J - 42 char
Function taking string on the right.
First we map the alphabet (
u:97+i.26
) into the numbers 0 through 25, all other characters (including spaces) going to 26 (i.
). Then we map ({~
) the first three elements map to the first key, the next three to the next key, and so on through the keys of the phone pad, making sure to map the space/other punctuation to a separate key at the end. (4 3 4 1,~5#3
is equal to3 3 3 3 3 4 3 4 1
andI.
turns that into a 27-item array where the first three are key 1, etc.) Then we check for pairwise inequality (2~:/\
) and AND all the results together (*/
).fonte
Racket, 119
Ungolfed (combinatoric regexing):
fonte
JavaScript - 152
Not a winner but I gave it a shot. Beats @Lozzaaa by 4 bytes as of posting time :)
Passes all the tests.
Takes advantage of JS's lack of typing to make a multi type array, and it takes advantage of indexOf returning -1 for space support.
Usage:
Assumes lowercase alphabetic characters and spaces only. Returns 1 for true, 0 for false.
Maybe if I knew ES6 I could try the second challenge...
fonte
ES6, JavaScript
8970 charactersI know its not a winner because when coming to handy operations like getting ASCII value of character, JS puts a lot of bloat (
.charCodeAt()
).Run it in Web Console of latest Firefox.
Usage:
The function returns either true or false.
EDIT: Golfed a lot using the
[...x].every
trick learned from @edc65 (Thanks!)I will try to golf it more :)
fonte
GML (Game Maker Language), 149
fonte
Python 3 - 152 chars
Not the shortest I could go, but it'll do for now
fonte