A maioria dos idiomas vem com um built-in para pesquisar uma string por todas as ocorrências de uma determinada substring e substituí-las por outra. Não conheço nenhuma linguagem que generalize esse conceito para subsequências (não necessariamente contíguas). Portanto, essa é sua tarefa neste desafio.
A entrada será composta por três cadeias A
, B
e C
, onde B
e C
são garantidas a ser do mesmo comprimento. Se B
aparecer como uma subsequência A
, deverá ser substituído por C
. Aqui está um exemplo simples:
A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345
Seria processado assim:
abcdefghijklmnopqrstuvwxyz
|| | ||
abcdef12ijklmn3pqr45uvwxyz
Se houver várias maneiras de encontrar B
como uma subsequência, você deve substituir avidamente a mais à esquerda:
A: abcdeedcba
B: ada
C: BOB
Result: BbcOeedcbB
and NOT: BbcdeeOcbB
O mesmo se aplica se B
puder ser encontrado em vários locais separados:
A: abcdeedcbaabcde
B: ed
C: 12
Result: abcd1e2cbaabcde
and NOT: abcd112cbaabc2e (or similar)
Quando B
não aparecer A
, a saída deve ser A
inalterada.
Regras
Como mencionado acima, pegue três cadeias e A
, como entrada, substitua a ocorrência mais à esquerda de como uma subsequência por , se houver alguma.B
C
B
A
C
Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e emitindo o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou parâmetro da função (saída).
Você pode pegar as três cadeias em qualquer ordem consistente que você deve especificar em sua resposta. Você pode assumir isso B
e C
ter o mesmo comprimento. Todas as seqüências conterão apenas caracteres alfanuméricos.
Aplicam-se as regras padrão de código de golfe .
Casos de teste
Cada caso de teste é quatro linhas: A
, B
, C
seguido pelo resultado.
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz
abcdeedcba
ada
BOB
BbcOeedcbB
abcdeedcbaabcde
ed
12
abcd1e2cbaabcde
121
121
aBc
aBc
abcde
acb
123
abcde
ABC
ABCD
1234
ABC
012345678901234567890123456789
42
TT
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
abcde
12345
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcbaedcba
abcde
12345
edcb1edc2aed3bae4cba5dcba
daccdedca
ace
cra
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
abaaaccbac
1223334444
aacbcbabcccaabcbabcaabbbbca
aacbcbabcccaabcbabcaabbbbcac
abaaaccbac
1223334444
1ac2cb2bccc33b3bab4aa4bbbc44
Entre os melhores
O snippet de pilha na parte inferior desta postagem gera classificações das respostas a) como uma lista da solução mais curta por idioma eb) como uma classificação geral.
Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:
## Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:
## Perl, 43 + 2 (-p flag) = 45 bytes
Você também pode transformar o nome do idioma em um link que será exibido no snippet:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
/* Configuration */
var QUESTION_ID = 77719; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 8478; // This should be the user ID of the challenge author.
/* App */
var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;
function answersUrl(index) {
return "http://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
function commentUrl(index, answers) {
return "http://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}
function getAnswers() {
jQuery.ajax({
url: answersUrl(answer_page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
answers.push.apply(answers, data.items);
answers_hash = [];
answer_ids = [];
data.items.forEach(function(a) {
a.comments = [];
var id = +a.share_link.match(/\d+/);
answer_ids.push(id);
answers_hash[id] = a;
});
if (!data.has_more) more_answers = false;
comment_page = 1;
getComments();
}
});
}
function getComments() {
jQuery.ajax({
url: commentUrl(comment_page++, answer_ids),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c);
});
if (data.has_more) getComments();
else if (more_answers) getAnswers();
else process();
}
});
}
getAnswers();
var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;
var OVERRIDE_REG = /^Override\s*header:\s*/i;
function getAuthorName(a) {
return a.owner.display_name;
}
function process() {
var valid = [];
answers.forEach(function(a) {
var body = a.body;
a.comments.forEach(function(c) {
if(OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});
var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match[2],
language: match[1],
link: a.share_link,
});
else console.log(body);
});
valid.sort(function (a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});
var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function (a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;
var answer = jQuery("#answer-template").html();
answer = answer.replace("{{PLACE}}", lastPlace + ".")
.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)
.replace("{{LINK}}", a.link);
answer = jQuery(answer);
jQuery("#answers").append(answer);
var lang = a.language;
lang = jQuery('<a>'+lang+'</a>').text();
languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
});
var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);
langs.sort(function (a, b) {
if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
return 0;
});
for (var i = 0; i < langs.length; ++i)
{
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
.replace("{{LINK}}", lang.link);
language = jQuery(language);
jQuery("#languages").append(language);
}
}
body { text-align: left !important}
#answer-list {
padding: 10px;
width: 290px;
float: left;
}
#language-list {
padding: 10px;
width: 290px;
float: left;
}
table thead {
font-weight: bold;
}
table td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="language-list">
<h2>Shortest Solution by Language</h2>
<table class="language-list">
<thead>
<tr><td>Language</td><td>User</td><td>Score</td></tr>
</thead>
<tbody id="languages">
</tbody>
</table>
</div>
<div id="answer-list">
<h2>Leaderboard</h2>
<table class="answer-list">
<thead>
<tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
</thead>
<tbody id="answers">
</tbody>
</table>
</div>
<table style="display: none">
<tbody id="answer-template">
<tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
<tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
[[1], [2], [3]]
.Respostas:
Geléia ,
232221 bytesExperimente online! Observe que os dois últimos casos de teste ficarão sem memória.
Verificação
Como funciona
fonte
Python 2, 88 bytes
Uma função que pega as três seqüências e gera o resultado para STDOUT. A função simplesmente passa a string, pegando o caractere apropriado e atualizando à
b,c
medida que avançamos.Para teste (depois de substituir o
print
porreturn
):fonte
Java 7, 141
Acho que posso fazer mais com isso, mas tenho que correr por enquanto. É apenas uma iteração / substituição simples, mantendo um índice em A e B.
Espaços em branco para o seu prazer:
fonte
Whitespaced
sim, isso é totalmente legívelj<k?a:d
Lua, 121 bytes
Solução simples,
gsub
permite iterar exatamente uma vez em cada caractere e substituí-los em uma nova instância da string.Ele recebe a entrada via 3 argumento da linha de comando e gera uma string para STDOUT.
Ungolfed
fonte
Python 3, 127 bytes.
Economizou 16 bytes graças a Katenkyo.
Ainda trabalhando um pouco nisso, o homem era mais desagradável do que eu pensava.
Explicação: Awww sim, recursão.
Casos de teste:
fonte
all(x in a for x in b)
também verifica se os elementos em be aparecem na mesma ordem, ou apenas se eles estiverem aqui?return a.replace(b[0],c[0],1)[:l(b[0])+1]+f(a[l(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else a
você salvar alguns bytes?Python 3.5, 87 bytes
repl.it para verificar todos os casos de teste .
Como funciona
'(.*?)'.join(p)
cria um padrão de pesquisa que corresponde à subsequência a ser substituída e qualquer coisa entre seus elementos.Como os quantificadores são preguiçosos, cada
(.*?)
um corresponderá ao mínimo de caracteres possível.Para o padrão
ghost
, o regex construído ég(.*?)h(.*?)o(.*?)s(.*?)t
.'\g<%d>'.join(r)%(*range(1,len(r)),)
cria a cadeia de substituição, usando a formatação da cadeia.Cada
\g<n>
refere-se ao n th grupo capturado, tal como\n
o faria.Para a substituição
12345
, a cadeia construída é1\g<1>2\g<2>3\g<3>4\g<4>5
.re.sub(...,...,s,1)
executa no máximo uma substituição na strings
.fonte
Pyth, 27
Suíte de teste
O conjunto de testes omite os dois últimos casos porque eles ficarão sem memória. O algoritmo usado aqui é encontrar todos os índices de cada caractere na segunda sequência da primeira sequência, encontrar todas as ordens possíveis desses índices e pegar apenas os que estão na ordem classificada. Em seguida, use o primeiro deles em ordem classificada como a lista de índices na primeira sequência para atualizar com os valores da terceira sequência.
Eu sinto que deveria haver algo mais curto que
.nM*F
...fonte
MATL , 33 bytes
Experimente online!
Explicação
fonte
JavaScript (ES6), 84 bytes
Explicação / Teste
Mostrar snippet de código
fonte
JavaScript (ES6),
8476 bytesPorque eu tinha certeza de que esse era um trabalho para o RegExp.
Editar: salvou 8 bytes graças a @ MartinBüttner ♦.
Uma porta da resposta Ruby de @ KevinLau levou 82 bytes:
Eu também tentei uma solução RegExp recursiva, mas que levou 90 bytes:
fonte
Julia,
8970 bytesUsa um índice
i
para percorrer as seqüências de padrão / substituição à medida que avançamos. -19 bytes graças a @Dennis!fonte
C, 98 bytes
/ * Código expandido * /
Os argumentos são: i ntrada cadeia, o utput tampão, s cadeia earch, r eplacement.
Depois de lembrar o início da entrada e da saída, passamos pela entrada, substituindo e avançando a substituição sempre que atingimos uma. No final, se ficarmos sem substituições, retorne o buffer de saída, senão a entrada não modificada.
/ * Testes * /
fonte
R, 76 bytes
usa
sub
para substituir a primeira correspondênciaUngolfed
fonte
C ++, 204 bytes
Golfe
Ungolfed
fonte
std
suficiente para justificar o usousing namespace std;
. Usandostd::cin
,std::cout
estd::string
vai economizar 5 bytes uma vez que aqueles parecem ser os únicos usos desse namespace.b
dentroa
, mas as letras posteriores também devem ser as letras anteriores. (Olhe caso de teste 3 e comparar com a sua saída, eu acho que você vai achar que o seu código seria de saídaabc21ed...
quando a saída esperada éabcd1e2...
!)Retina , 63 bytes
A entrada é feita na ordem
B
,C
,A
, separados por alimentações de linha.Experimente online.
fonte
Haskell, 87 bytes
Percebi a falta de uma resposta Haskell e decidi consertar isso. Isso define uma função ternária
!
com ordem de argumento padrão-substituição-sequência. Experimente aqui.Explicação
A função auxiliar
#
pega uma listax
de pares de caracteres (padrão e substituição) e uma stringy
. Se os caracteres "padrão"x
formarem uma subsequência dey
, ele retornará a lista vazia ey
com cada caractere padrão substituído por sua contraparte. Caso contrário, ele retornará o par(x,y)
. A função!
fecha o padrão e substitui as seqüências de caracteresx
, aplica#
- se àx
terceira sequência e retorna o segundo componente do resultado.Se o padrão for uma subsequência da sequência, o código será executado em O (n) tempo, fazendo uma passagem recursiva pela sequência e construindo avidamente a substituição no processo. No entanto, se o padrão não for uma subsequência, ele será executado no tempo O (2 n ) no pior caso. Isso ocorre porque em todas as posições em que o padrão e a string têm um caractere correspondente, a função se chama para verificar se o padrão é realmente uma subsequência, descobre que não é e se chama uma segunda vez para calcular o resultado.
fonte
JavaScript (ES6),
10095 bytesEsta é uma função JavaScript Lambda válida. Saídas como função
return
. Aceita três argumentos (a,b,c
). Adicionef=
no início e chame likef(arg1,arg2,arg3)
.fonte
f=
menos que sua função seja recursiva, mas não pareça.a
não contiver o padrão. Também não tenho certeza de que retornar uma matriz de seqüências de caracteres seja aceitável.C (gcc),
67626159 bytesExperimente online!
fonte
Oitava, 97 bytes
Iterar sobre a subsequência para substituir; encontre a primeira ocorrência do primeiro caractere, encontre o próximo caractere na sequência restante, repita. O um pouco interessante disso é:
Como o ideone ainda não está aceitando funções com nomes diferentes de '', deixarei apenas uma amostra executada aqui. As entradas são mostradas apenas para os primeiros casos de teste por questões de brevidade.
key
é a saída esperada,ans
é a saída da função.fonte
D(t=...)
) manter-me intrigante :-)Python 3, 123 bytes
Uma abordagem diferente que eu queria compartilhar, que é alguns bytes mais curta. Não há regras contra a biblioteca / regex padrão, certo?
PS. Este é o meu primeiro golfe. Deixe-me saber de quaisquer problemas / melhorias.
fonte
Pitão, 22 bytes
Verifique todos os casos de teste no Pyth Compiler .
fundo
Construímos uma regex a partir do padrão acrescentando ae
$
colocando(.*?)
entre todos os caracteres. Essa regex corresponderá à subsequência a ser substituída e qualquer coisa entre seus elementos e qualquer coisa até o final da string.Como os quantificadores são preguiçosos, cada
(.*?)
um corresponderá ao mínimo de caracteres possível.Para o fantasma padrão, o regex construído é
g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$
.Se o padrão corresponder à entrada, o padrão
r<str><regex>3
-in retornará uma matriz contendo o prematch (tudo antes da subsequência), todos os grupos capturados (tudo entre e após a subsequência) e o postmatch (a sequência vazia).Se o padrão não corresponder, o built-in retornará uma matriz singleton contendo a entrada original.
Como funciona
fonte
Gelatina , 23 bytes
Isso é dois bytes mais longo do que minha outra resposta Jelly , mas termina instantaneamente. Experimente online!
Verificação
Como funciona
fonte
CJam, 29 bytes
Experimente online! ou verifique todos os casos de teste .
fonte
Java 7, 102 bytes
Teste detalhado aqui
fonte
Julia,
939086 bytesTer que testar separadamente se a partida foi bem-sucedida destrói o placar. Uma substituição exigiria a transmissão
Base.SubstitutionString
, o que provavelmente não vale a pena ...Execução de teste
fonte
Julia,
625958 bytesA E / S está na forma de matrizes de caracteres.
Verificação
fonte
PHP,
130109 bytesEu ainda gostaria que fosse mais curto; poderia salvar 3 bytes (
""<
) se nãoB
fosse garantido0
.recebe argumentos da linha de comando. Corra com
-r
.Substitui os caracteres quando os encontra;
imprime cópia se todos os caracteres foram substituídos; original mais.
fonte
Ruby,
70645958 bytesFunção anônima. Percorra a sequência
a
para criar uma nova sequência com as letras substituídas de acordo com o próximo caractereb
ec
, se todos os caracteresb
estiverem esgotados no final, retorne a sequência recém-construída, caso contrário, retorne a sequência original.@histocrat ajudou a economizar 6 bytes via
gsub
.Guardou 1 byte graças a @Cyoce.
Experimente online!
fonte
-1+i+=1
por~-i+=1
Perl, 80 + 1 = 81 bytes
Corra com a
-p
bandeiraExperimente online!
O código gera procedimentalmente um comando regex de pesquisa e substituição, que é executado no último bit de código.
A sequência
ghost
no primeiro exemplo é transformada em sequênciag(.*?)h(.*?)o(.*?)s(.*?)t(.*?)
, o que significa umg
seguido por 0 ou mais caracteres, seguido por umh
seguido por 0 ou mais caracteres, seguido por etc.*?
quantificador significa que a pesquisa deve ser não gulosa e "devorar" "o menor número possível de caracteres, em vez do padrão de corresponder o máximo possível.A cadeia de caracteres
12345
é então transformada1 .$1.2 .$2.3 .$3.4 .$4.5 .$5
, avaliada após a execução da regex. Cada um deles$1,$2,$3,$4,$5
é realmente uma referência anterior a um grupo de captura (entre parênteses) da primeira sequência.fonte
perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'
. Inventei sozinho, mas é bem parecido com o seu, então não vou publicá-lo, seriam duas respostas muito próximas, mas fique à vontade para editar as suas!perl -E 'chomp(($f,$t,$s)=(<>));$f=join"(.*?)",split"",$f;@r=split"",$t;@t=shift@r;push@t,"\${",++$x,"}"for(@r);$t=join"",@t;say$s=~s/$f/$t/r;'
Clojure, 113 bytes
Um básico
reduce
, não muito feliz com todos esses longosfirst
,rest
econj
chamadas de função. Na esperança de ver uma abordagem melhor.fonte