Pegue a primeira letra de cada palavra, deixe espaços e pontuação

8

Reduza cada palavra em uma sequência de grupos de seqüências de caracteres em letras únicas delineadas por espaços ou pontuação.

Exemplo

I'm a little teapot,  short and stout. Here is my handle, here is my spout. When I get all steamed up - hear me shout!   Tip me over and pour me out. 

torna-se

I' a l t, s a s. H i m h, h i m s. W I g a s u - h m s! T m o a p m o. 

Editar - se houver vários espaços, preserve apenas um espaço. Toda pontuação deve ser preservada, perdi o apóstrofo. Sim, este é o código golf :-).

Cthanatos
fonte
1
Pode haver vários espaços entre as palavras? Temos que preservá-los?
Dennis
8
Além disso, quais caracteres contam exatamente como pontuação?
Dennis
1
Qual é o comportamento exigido para números ou outros caracteres além de pontuação ( +etc.)
grovesNL
1
Haverá mais de uma pontuação em uma palavra? Algo como O'Leary-Clarence-DeVoisse tornaria O'--?
Hmatt1 24/05
8
Você pode aceitar uma resposta sempre que quiser, mas é melhor deixar algum tempo (dias) antes de encerrar um desafio.
edc65

Respostas:

5

CJam, 13 bytes

r{(\'A,f&Sr}h

Funciona se eu puder considerar apenas os caracteres de pontuação comuns e a saída pode ter espaços à direita. (Obrigado a Dennis.)

Esta questão precisa de muito mais esclarecimentos ...

CJam, 17 16 bytes

r{(\eu_elf&Sr}h&

Experimente online .

Explicação

r          e# Read one word from input.
{          e# While it is not EOF:
    (\     e# Extract the first character.
    eu     e# Convert the rest to uppercase.
    _el    e# And lowercase.
    f&     e# Delete characters in the first string if not in the second string.
    S      e# Append a space.
    r      e# Read the next word.
}h
&          e# Discard the last space by intersecting with empty string.
jimmy23013
fonte
Você pode adicionar um link para testá-lo, por favor? Estou no celular.
Cthanatos
@Cthanatos Added.
Jimmy23013
1
rempurra uma string vazia no EOF, então isso também funciona:r{(\eu_elf&Sr}h;
Dennis
1
@ Dennis Tenho certeza de que já vi código assim muitas vezes, mas ainda não me lembro ... Obrigado. Mas isso ;não faz sentido então.
Jimmy23013 25/05
1
Se necessário, você ainda pode se livrar dele &. Além disso, dependendo do que conta exatamente como pontuação, '@,seria uma alternativa mais curta eu_el.
Dennis
4

Pitão, 14 bytes

jdm+hd-rtd0Gcz

Experimente online: Demonstração

Explicação:

                 implicit: z = input string
            cz   split z by spaces
  m              map each word d to:
    hd              first letter of d
   +                +
       rtd0         (lowercase of d[1:]
      -    G         but remove all chars of "abc...xyz")
jd               join resulting list by spaces and print
Jakube
fonte
Isso está duplicando hífens?
Cthanatos
@Cthanatos Deve funcionar agora.
Jakube 24/05
@grovesNL você consegue pensar em uma frase que alguém possa encontrar por escrito regularmente, ou seja, um livro, uma notícia onde os números em uma frase podem ser um problema ou surgir?
Cthanatos
@Cthanatos: Existem muitos casos em que números são usados ​​em livros ou artigos de notícias. " Mais de 200 entrevistados ... " " O lote tem 50 acres ... " " É capaz de armazenar aproximadamente 20 litros ... "
grovesNL
Touché ... Bom ponto.
Cthanatos
2

Python 3.4, 94 92 82 77 bytes

print(*[w[0]+''.join(c[c.isalpha():]for c in w[1:])for w in input().split()])

Eu sou novo em codificar golfe, mas pensei em tentar! Este não é um vencedor, mas foi divertido.

Isso apenas divide a string, levando o primeiro caractere de cada palavra junto com qualquer pontuação no restante da palavra.

* editado com alterações por FryAmTheEggman, DLosc

Robotato
fonte
Você pode usar o argumento com estrela do python passando para salvar alguns bytes e a inversão da condição parece economizar 1 byte (embora ainda pareça suspeitamente jogável). Aqui está o que eu tenho:print(*[w[0]+''.join([c for c in w[1:]if 1-c.isalpha()])for w in input().split()])
FryAmTheEggman
@FryAmTheEggman Ah, obrigado! Eu esqueci a discussão estrelada.
Robotato 25/05
2
Não há necessidade de colchetes em torno da compreensão interna - joinpode usar um gerador simples como argumento. Além disso, aqui está uma forma cadeia de corte de fazer a lógica "se não isalpha": c[c.isalpha():]for c in w. Você deve descer para 77 bytes. : ^)
DLosc
@DLosc Esse truque para cortar cordas é inteligente, obrigado! Vou ter que lembrar disso.
Robotato 25/05
1

sed (39 caracteres)

Apenas algumas expressões regulares:

sed 's+\<\(.\)[A-Za-z]*+\1+g;s+  *+ +g'
joeytwiddle
fonte
2
Normalmente, não contamos o nome do intérprete e a sintaxe adicional exigida pelo shell para passar o código ou os dados corretamente para o intérprete. Seu código Sed atual possui apenas 32 caracteres.
manatwork
1

Lua - 126 caracteres

Lua não é uma linguagem de código de golfe, mas eu tentei:

a=''for b in string.gmatch( c, '%S+%s?' )do d=(b:match('%w')or''):sub(1,1)e=b:match('[^%s%w]')or''a=a..d..e..' 'end print( a )

Isso pressupõe que cé a string.

Aqui está limpo para facilitar a leitura:

local string = [[I'm a little teapot,  short and stout. Here is my handle, here is my 
spout. When I get all steamed up - hear me shout!   Tip me over and pour me out.]]

local final = ''
for word in string.gmatch( string, '%S+%s?' ) do 
    local first = ( word:match( '%w' ) or '' ):sub( 1, 1 )
    local second = word:match( '[^%s%w]' ) or ''
    final = final .. first .. second .. ' '
end
print( final )

Você pode testá-lo aqui (copie e cole. Pela primeira vez, você também precisa fazer c = "I'm a little ....) Por algum motivo, a demonstração on-line de Lua não permitirá que você insira variáveis ​​usando io.read...

DavisDude
fonte
1

PowerShell, 56 bytes

%{($_-split' '|%{$_[0]+($_-replace'[a-z]','')})-join' '}
Nacht - Restabelecer Monica
fonte
1

Javascript ( ES6 ) 72 68 bytes

f=x=>x.split(/\s+/).map(x=>x.replace(/^(.)|[a-z]/gi,'$1')).join(' ')
<input id="input" value="I'm a little teapot,  short and stout. Here is my handle, here is my spout. When I get all steamed up - hear me shout!   Tip me over and pour me out. " />
<button onclick="output.innerHTML=f(input.value)">Run</button>
<br /><pre id="output"></pre>

Comentado:

f=x=>
    x.split(/\s+/). // split input string by 1 or more spaces
    map(x=> // map function to resulting array
        x.replace(/^(.)|[a-z]/gi, '$1') // capture group to get the first character
                                        // replace all other letters with empty string
    ).
    join(' ') // join array with single spaces
nderscore
fonte
1

C99 - 170 169 bytes

main(_,a)char**a;{for(char*b=a[1],*c=b,*e,*d;*c++=*b;){for(e=b;*++b&&*b-32;);for(*b=0,d=strpbrk(e,"!',-."),d&&d-e?*c++=*d:0;b[1]==32;++b);++b;*c++=32;*c=0;}puts(a[1]);}

Ungolfed:

main(int argc, char**a) {
    char*b=a[1],*c=b,*e,*d;
    while(*c++=*b){
        for(e=b;*++b&&*b-32;); //scan for first space or end of word
        *b=0; //mark end of word
        for(;b[1]==32;++b); //skip following spaces
        d=strpbrk(e,"!',-."); //find punctuation
        if(d&&d-e) //append punctuation if any, and it's not the word itself
            *c++=*d;
        *c++=32; //append space
        b++;
    }
    *c=0; //mark end of line
    puts(a[1]);
}

Uso:

gcc -std=c99 test.c -o test
./test "I'm a little teapot,  short and stout. Here is my handle, here is my spout. When I get all steamed up - hear me shout!   Tip me over and pour me out."

Resultado:

I' a l t, s a s. H i m h, h i m s. W I g a s u - h m s! T m o a p m o.
rr-
fonte
1

Java 8, 87 bytes

s->{for(String x:s.split(" +"))System.out.print(x.replaceAll("^(.)|[a-z]+","$1")+" ");}

Explicação:

Experimente aqui.

s->{                                  // Method with String parameter and no return-type
  for(String x:s.split(" +"))         //  Split the input on one or multiple spaces
                                      //  And loop over the substrings
    System.out.print(                 //   Print:
      x.replaceAll("^(.)|[a-z]+","$1")//    Regex to get the first letter + all non-letters
      +" ");                          //    + a space delimiter
                                      //  End of loop (implicit / single-line body)
}                                     // End of method

Explicação Regex:

x.replaceAll("^(.)|[a-z]+","$1")
x.replaceAll("           ","  ") # Replace the match of String1 with String2, in String `x`
             "           "       # Regex to match:
              ^(.)               #  The first character of String `x`
                  |[a-z]+        #  Or any one or multiple lowercase letters
                           "  "  # Replace with:
                            $1   #  The match of the capture group (the first character)

Portanto, basicamente remove todas as letras minúsculas de uma String, exceto a primeira.

Kevin Cruijssen
fonte
0

R, 46 45 bytes

cat(gsub("^\\w\\W*\\K\\w*","",scan(,""),T,T))

Isso lê uma linha de STDIN e imprime em STDOUT. Ele usa uma expressão regular para remover todos os caracteres após a primeira letra seguida por qualquer quantidade de pontuação.

Ungolfed + explicação:

# Read a string from STDIN and convert it to a character vector,
# splitting at spaces

input <- scan(what = "")

# Replace stuff with nothing using a regex.
# ^ start position anchor
# \w single "word" character
# \W* any amount of non-word (i.e. punctuation) characters
# \K move the match position forward
# \w* any number of word characters

replaced <- gsub("^\\w\\W*\\K\\w*", "", input, ignore.case = TRUE, perl = TRUE)

# Print the vector elements to STDOUT, separated by a space

cat(replaced, sep = " ")

Exemplo:

> cat(gsub("^\\w\\W*\\K\\w*","",scan(,""),T,T))
1: I'm a little teapot,  short and stout. Here is my handle, here is my spout. When I get all steamed up - hear me shout!   Tip me over and pour me out. 

I' a l t, s a s. H i m h, h i m s. W I g a s u - h m s! T m o a p m o.
Alex A.
fonte
0

05AB1E , 13 bytes

#õKεćsDáмJ}ðý

Experimente online!

Explicação:

#õKεćsDáмJ}ðý  Full program
#              Split on spaces
 õK            Remove empty strings from the list
   ε           For each...
    ć             push a[1:], a[0]
     s            Swap
      D           Duplicate
       á          Push only letters of a
        м         pop a,b => push a.remove(all elements of b)
         J        Join
          }    End for each
           ðý  Join with spaces
escoteiro
fonte
0

VBA (Excel), 141 133 bytes

Usando a janela imediata do VBA, [A1] como seqüências de caracteres inseridas.

z=" "&[A1]:for a=2 to len(z):c=mid(z,a,1):[A2]=[A2]&IIF(mid(z,a-1,1)=" ",c,IIF(asc(lcase(c))>96 and asc(lcase(c))<123,"",c)):next:?[TRIM(A2)]

z=" "&[a1]:for a=2 to len(z):c=mid(z,a,1):e=asc(lcase(c)):[a2]=[a2]&iif(mid(z,a-1,1)=" ",c,IIF((e>96)*(e<123),"",c)):next:?[TRIM(A2)]
remoel
fonte