Gerar uma sigla


19

Isso é semelhante a Criar um acrônimo , mas há várias diferenças importantes, incluindo o método de buscar o acrônimo, e esse desafio, incluindo saída flexível.

Tarefa

Dada uma sequência (lista de caracteres / comprimento 1 é permitida) contendo apenas ASCII imprimível, imprima todas as letras maiúsculas na entrada que são precedidas por um espaço ou um traço ou são o primeiro caractere na entrada. String vazia é um comportamento indefinido.

Casos de teste:

Saída pode estar no formato de "TEST", ["T","E","S","T"]ou o que quer que mais funciona para você.

Self-contained Underwater Breathing Apparatus
SUBA

a Programming Language
PL

NATO Atlantic TREATY Organization
NATO

DEFCON 2
D

hello, world!


light-Emitting dioDe
E

What Does the Fox Say?
WDFS


3D mov-Ies
I

laugh-Out Lou-D
OLD

Best friends FOREVE-r
BF

--


<space>


--  --a -  - --


--  -- -  - -- A
A

Step-Hen@Gmail-Mail Mail.CoM m
SHMM

Isso é , então a resposta mais curta em bytes vence.



Podemos considerar a entrada como uma lista de Strings (lista de caracteres)?
Mr. Xcoder

@ Mr.Xcoder sim.
Stephen

Você pode adicionar um caso de teste que inclua algumas letras separadas por um ou mais caracteres que não sejam letras, números, espaços ou traços. Um endereço de e-mail, por exemplo: My-Name@Some-Domain.TLD.
Shaggy

11
@ Shaygy acrescentou, obrigado.
Stephen

Respostas:


8

V , 7 bytes

ÍÕü¼À!õ

Experimente online!

Aqui está um hexdump para provar a contagem de bytes:

00000000: cdd5 fcbc c021 f5                        .....!.

Explicação:

Í       " Search and replace all occurrences on all lines:
        " (Search for)
 Õ      "   A non-uppercase letter [^A-Z]
  ü     "   OR
      õ "   An uppercase letter
    À!  "   Not preceded by...
   ¼    "   A word-boundary
        " (implicitly) And replace it with:
        "   Nothing

Este é curto tudo graças ao maravilhoso do V compressão regex .


Isso é muito curta 0.o
Stephen

@StepHen Por que obrigado! Eu acho que isso é bem próximo do ideal. :)
DJMcMayhem

2
O que você quer dizer com limite de uma palavra? A questão parece sugerir que apenas espaço e -são permitidos.
Neil

8

R , 66 63 bytes

function(s)(s=substr(strsplit(s,' |-')[[1]],1,1))[s%in%LETTERS]

Experimente online!

-3 bytes graças ao Scarabee

Uma função anônima; retorna o acrônimo como um vetor c("N","A","T","O")que é impresso implicitamente.

Pela primeira vez, isso não é tão ruim no R! divide em -or (space), pega o primeiro elemento de cada um deles e retorna os que são maiúsculos ( LETTERSé um R embutido com letras maiúsculas), em ordem.


Eu acho que você pode salvar alguns bytes:function(s)(s=substr(strsplit(s,' |-')[[1]],1,1))[s%in%LETTERS]
Scarabee

11
@Scarabee obrigado. Desculpe, demorou 2 anos para atualizar.
Giuseppe


5

Javascript 21 bytes

Pega uma entrada de string e gera uma matriz de strings contendo os caracteres acrônimos

x=>x.match(/\b[A-Z]/g)

Explicação

É apenas uma correspondência regex global para o limite de palavras seguido por uma letra maiúscula.



4

Dyalog APL, 29 23 bytes

Caso de teste de bônus: uma linguagem de programação (APL).

'(?<=^| |-)[A-Z]'⎕S'&'⊢

Retorna uma matriz de caracteres (mostra como o espaço separado no TIO).

Experimente online!


Postagem mais antiga, 29 bytes

{(⎕AV~⎕A)~⍨'(\w)\w+'⎕R'\1'⊢⍵}

Experimente online!

Quão?

'(\w)\w+'⎕R - substitua cada agrupamento de caracteres alfabéticos

    '\1' - com seu primeiro caractere

~⍨ - remover todos os caracteres

    (⎕AV~⎕A) - que não é uma maiúscula ASCII


3

Python, 53 bytes

import re
lambda s:re.findall("(?<=[ -])[A-Z]"," "+s)

Experimente online!

Uma expressão regular simples, com um lookahead para espaço ou traço. Em vez de corresponder ao início, coloque um espaço antes.


Editado em um link TIO com a suíte de testes do MrXCoder.
Stephen

Graças @StepHen - você chegou antes de mim e me salvou o esforço
Chris H


3

C #, 84 78 bytes

using System.Linq;s=>s.Where((c,i)=>c>64&c<91&(i>0?s[i-1]==32|s[i-1]==45:1>0))

Guardado 6 bytes graças a @jkelm .

Experimente online!

Versão completa / formatada:

using System.Collections.Generic;
using System.Linq;

class P
{
    static void Main()
    {
        System.Func<string, IEnumerable<char>> f = s => s.Where((c, i) => c > 64 & c < 91 & (i > 0 ? s[i-1] == 32 | s[i-1] == 45: 1 > 0));

        System.Console.WriteLine(string.Concat(f("Self-contained Underwater Breathing Apparatus")));
        System.Console.WriteLine(string.Concat(f("a Programming Language")));
        System.Console.WriteLine(string.Concat(f("NATO Atlantic TREATY Organization")));
        System.Console.WriteLine(string.Concat(f("DEFCON 2")));
        System.Console.WriteLine(string.Concat(f("hello, world!")));
        System.Console.WriteLine(string.Concat(f("light-Emitting dioDe")));
        System.Console.WriteLine(string.Concat(f("What Does the Fox Say?")));
        System.Console.WriteLine(string.Concat(f("3D mov-Ies")));
        System.Console.WriteLine(string.Concat(f("laugh-Out Lou-D")));
        System.Console.WriteLine(string.Concat(f("Best friends FOREVE-r")));
        System.Console.WriteLine(string.Concat(f(" ")));
        System.Console.WriteLine(string.Concat(f("--  --a -  - --")));
        System.Console.WriteLine(string.Concat(f("--  -- -  - -- A")));

        System.Console.ReadLine();
    }
}

Por que você precisa incluir using System.Linqna contagem de bytes se using System.Collections.Genericestá isento? Existe algum consenso sobre quais usingsão contáveis?

@DaveParsons using System.Linq;é necessário para o código Linq na minha resposta. No entanto, IEnumerbale<char>não faz parte da resposta e essa é a parte do código que precisa using System.Collections.Generic;ser compilada.
TheLethalCoder

faz sentido; obrigado pela clarificação.

Você pode salvar alguns bytes verificando maiúsculas usando os caracteres como ints. c> 64 & c <91 deve gerar 6 bytes.
jkelm

@jkelm Nice :) Eu sempre esqueço esse truque!
TheLethalCoder

3

Julia 0.6.0 (57 bytes)

s=split(s,r" |-");for w∈s isupper(w[1])&&print(w[1])end

Explicação: Este é o meu primeiro código-golfe. Bem direto. Divida as palavras, imprima a primeira letra superior de cada uma.

Provavelmente é fácil fazer melhor usando regex, mas eu sou novo nesse


11
Bem-vindo ao PPCG! Estou sem votos agora, vou votar mais tarde.
21417 Stephen

2
@StepHen Eu tenho coberto. : P
DJMcMayhem


2

C # (.NET Core) , 108 bytes

n=>{var j="";n=' '+n;for(int i=0;++i<n.Length;)if(" -".IndexOf(n[i-1])>=0&n[i]>64&n[i]<91)j+=n[i];return j;}

Experimente online!


Não foi verificado, mas alterar ifpara um ternário pode economizar bytes. Isso inicia no índice 2, em vez de 1, simplesmente mudar int i=1para int i=0corrigi-lo. Fora isso, acho que não há muito mais a fazer aqui.
TheLethalCoder

Um ternário não ajudaria aqui, pois seria a mesma contagem de bytes que uma declaração if. No entanto, você está correto em que eu preciso mudar a inicial i valor
jkelm

Eu não tinha muita certeza, mas eles geralmente saem mais curtos, por isso sempre vale a pena conferir.
TheLethalCoder

2

Geléia ,  11  10 bytes

-1 byte graças a Erik the Outgolfer ( divide em espaços> _ <)

⁾- yḲḢ€fØA

Um link monádico que recebe e retorna listas de caracteres.
Como um programa completo, aceita uma string e imprime o resultado.

Experimente online! ou veja uma suíte de testes .

Quão?

⁾- yḲḢ€fØA - Link: list of characters, x       e.g. "Pro-Am Code-golf Association"
   y       - translate x with:
⁾-         -   literal list of characters ['-',' '] "Pro Am Code golf Association"
    Ḳ      - split at spaces               ["Pro","Am","Code","golf","Association"]
     Ḣ€    - head each (1st character of each)      "PACgA"
        ØA - yield uppercase alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
       f   - filter keep                            "PACA"
           - if running as a full program: implicit print

Umm, por que não usar em vez de ṣ⁶?
Erik the Outgolfer

Heh, porque eu esqueci. Obrigado!
27617 Jonathan Allan

2

Perl 5 , 25 bytes

Código de 24 bytes + 1 para -n.

Irritante que grep -Psuporta comprimento variável look-behind, mas Perl não :(.

print/(?:^| |-)([A-Z])/g

-1 byte graças a @Dada !

Experimente online! - inclui -lexecutar todos os testes de uma só vez.


Você pode fazer muito melhor: experimente online! ;-)
Dadá

@Dada Hah! Claro ... Estou fora do caixa eletrônico, mas vou atualizar quando voltar. Obrigado! Estou muito desapontado que eu não poderia começar s///ou $_=para negar o print...
Dom Hastings

Sim, estava procurando um single s///para resolver isso, mas não é óbvio ... Estou no trabalho, talvez tente mais tarde!
Dada


2

Braquilog , 25 23 22 bytes

,Ṣ↻s₂ᶠ{h∈" -"&t.∧Ạụ∋}ˢ

Experimente online!

(-2 bytes graças a @Fatalize.)

,Ṣ↻                      % prepend a space to input
   s₂ᶠ                   % get all substrings of length 2 from that, to get prefix-character pairs
      {              }ˢ  % get the successful outputs from this predicate: 
       h∈" -"              % the prefix is - or space
               &t.∧        % then the character is the output of this predicate if:
                  Ạụ∋        % the alphabet uppercased contains the character

Você pode usar em vez de " "salvar dois bytes
Fatalize


2

Swift 5 , 110 bytes

-5 graças a Coeur

import UIKit
func f(s:[String]){for i in zip(s,[" "]+s){if i.0.isUppercase()&&"- ".contains(i.1){print(i.0)}}}

Explicação detalhada

  • import Foundation- Importa o módulo Foundationessencial para zip()a parte principal deste código.

  • func f(s:[String]){...}- Cria uma função com um parâmetro s, que é uma lista de Strings, representando os caracteres da entrada.

  • for i in zip(s,[" "]+s){...}- Repete iatravés do zip da entrada e da entrada com um espaço adicionado no início, o que é muito útil para obter o caractere anterior na String.

  • if - Verifica se:

    • i.0==i.0.uppercased() - O caractere atual é maiúsculo,

    • &&"- ".contains(i.1) - e Se o caractere anterior for um espaço ou um traço.

  • Se as condições acima forem atendidas, então:

    • print(i.0) - O caractere é impresso, porque faz parte da sigla.

-5 com em import UIKitvez de import Foundation.
Cœur



1

Python 3 , 73 70 bytes

lambda n:[n[x]for x in range(len(n))if'@'<n[x]<'['and(' '+n)[x]in' -']

Experimente online!


Explicação

  • lambda n:- Cria uma função lambda anônima com um parâmetro String n.

  • n[x]- Obtém o caractere de nno índice x.

  • for x in range(len(n))- Repete 0o comprimento de n, nomeando a variável x.

  • if - Verificações:

    • '@'<n[x]<'[' - Se o caractere estiver em maiúsculas,

    • and(' '+n)[x]in' -'- E se for precedido por um espaço ou um traço na String formada por um espaço e n.


2
É ruim ler isso como i suppere não faço ideia do porquê?
TheLethalCoder

@TheLethalCoder É .isupper(), eu não tenho idéia do que você lê: p
Mr. Xcoder





1

Bash (grep), 29 28 bytes

grep -oP'(?<=^| |-)[A-Z]' a

Uma porta da minha resposta python, mas porque pgrep suporta lookbehinds de comprimento variável, é visivelmente mais curta (mesmo considerando a sobrecarga do python). Cole os casos de teste em um arquivo chamadoa , a saída é de 1 caractere por linha.

-1 Obrigado a Neil


^| |-pode ser um teste mais curto?
Neil

@ Neil que funciona aqui, obrigado. Perdeu, porque ele não funciona em Python
Chris H

1

RProgN 2 , 18 bytes

`-` rû#ùr.'[a-z]'-

Explicado

`-` rû#ùr.'[a-z]'-
`-`                     # Push "-" literal, and " " literal.
    r                   # replace, Replaces all "-"s with " "s.
     û                  # Split, defaultly by spaces.
      #ù                # Push the head function literally.
        r               # Replace each element of the split string by the head function, which gets each first character.
         .              # Concatenate, which collapses the stack back to a string.
          '[a-z]'-      # Push the string "[a-z]" literally, then remove it from the string underneith, giving us our output. 

Experimente online!


1

PHP, 62 bytes

for(;~$c=$argn[$i++];$p=$c!="-"&$c!=" ")$c<A|$c>Z|$p?:print$c;

Execute como pipe -nRou experimente on-line .

outras soluções:

foreach(preg_split("#[ -]#",$argn)as$s)$s[0]>Z|$s<A?:print$s[0];  # 64 bytes
preg_match_all("#(?<=\s|-)[A-Z]#"," $argn",$m);echo join($m[0]);  # 64 bytes
preg_match_all("#(?<=\s|-)\p{Lu}#"," $argn",$m);echo join($m[0]); # 65 bytes

1

C ++, 168 bytes

#include<string>
auto a=[](auto&s){auto r=s.substr(0,1);if(r[0]<65||r[0]>90)r="";for(int i=1;i<s.size();++i)if(s[i]>64&&s[i]<91&&(s[i-1]==32||s[i-1]==45))r+=s[i];s=r;};

Saída realizada através do parâmetro


Seria possível remover completamente #include<string>e assumir que o argumento sé um std::string?
Zacharý 5/10

1

Lua , 79 75 bytes

for i=1,#t do for i in(" "..t[i]):gmatch"[%-| ]%u"do print(i:sub(2))end end

Tente!

Coloquei um print () antes do final na versão try it, porque, caso contrário, está uma bagunça. Esse programa segue perfeitamente os requisitos de E / S e correspondência, mas sem essa nova linha extra, é muito difícil de ler.

A entrada é fornecida na forma de uma tabela de número: string, número incrementando em 1 a cada vez e começando em 1.

Explicação:

Ele faz loops através de uma combinação de cada sequência de entrada. A pesquisa gmatch é a seguinte:

[% - | ] - Agrupe, pesquise um - ou um espaço

% u - pesquisa por um caractere maiúsculo

Em seguida, para cada partida, imprime menos o traço ou espaço anterior

Edit: Golfed 4 bytes removendo a declaração de 'a' e adicionando o espaço à entrada dentro do loop for, além de alterar a sub-entrada para apenas 2 em vez de 2,2 (que produz resultados equivalentes)


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.