한 글자 스왑


18

postcount ++라는 웹에서 가장 큰 포럼이 새로운 포럼 게임을 만들기로 결정했습니다. 이 게임에서 목표는 단어를 게시하는 것이지만 단어에는 하나의 문자를 추가, 제거 또는 변경해야합니다. 더 지능적인 포럼 게임을 통해보다 지능적인 포럼을 가지고 경쟁을 파괴하고자하는 회사에서 일할 때 상사는 단어와 UNIX 사전을 얻는 프로그램을 작성하기를 원했습니다. 그와 이야기를 나누면 어쨌든 직장에서 많은 현금을 얻습니다).

프로그램은 단어와 사전이라는 두 가지 인수를받습니다. 프로그램을 관리하는 사용자 (예, 사용자, 회사에 봇을 실행할 리소스가 없음)가 완벽하지 않기 때문에 두 경우 모두 사례를 정규화해야합니다. 사전의 단어는 ASCII 문자 (대문자와 소문자 모두)를 사용할 수 있지만 비교 중에는 무시해야합니다. 78자를 넘지 않아야합니다. 단어를 수동으로 생각하는 사람들의 재미를 없애기 위해 게임에서 허용되는 단어 목록을 출력해야합니다.

다음은 유사한 단어를 확인하는 예상 프로그램의 예입니다 golf.

> ./similar golf /usr/share/dict/words
Goff
Wolf
gold
golfs
goof
gulf
wolf

다음 /usr/share/dict/words은 줄 바꿈이있는 단어 목록입니다. 예를 들어 fgets ()로 쉽게 읽을 수 있습니다.

당신이 일하는 회사는 펀치 카드가 많지 않습니다 (예, 2014 년이며 여전히 펀치 카드를 사용합니다). 낭비하지 마십시오. 가능한 짧은 프로그램을 작성하십시오. 아, 그리고 당신은 Levenshtein 거리 또는 이와 유사한 알고리즘의 내장 또는 외부 구현을 사용하지 말 것을 요청했습니다. Not Invented Here 또는 백도어에 대한 것 (공급 업체가 언어에 삽입 한 것으로 보입니다) (언어에 대한 증거는 없지만 상사와상의하지 마십시오). 따라서 거리를 원한다면 직접 구현해야합니다.

모든 언어를 자유롭게 사용할 수 있습니다. 펀치 카드를 사용하더라도이 회사는 Cobol Ruby 또는 Haskell 과 같은 최신 프로그래밍 언어 또는 원하는 모든 것에 액세스 할 수 있습니다. 문자열 조작에 좋다고 생각한다면 GolfScript도 있습니다 (아마도 모르겠습니다 ...).

승자는 저에게서 15 점의 평판을 얻었고, 아마도 커뮤니티에서 다른 많은 점을 얻었을 것입니다. 다른 좋은 답변은 10 점을 얻었으며 커뮤니티에서도 점수를 얻습니다. 포인트는 쓸모 없다고 들었지만 2050 년에는 포인트를 대체 할 가능성이 높습니다. 그러나 확인되지는 않았지만 어쨌든 포인트를 얻는 것이 좋습니다.


6
우리는 "레 벤슈 테인 거리 또는 유사한 알고리즘의 내장 또는 외부 구현을 사용하지 말아야합니까?" 30 자 Mathematica 솔루션이 있습니다.
Michael Stern


2
codegolf.stackexchange.com/questions/6939/… 와 거의 동일합니다 .
Howard

"루비 나 하스켈 같은"-알았어. 내가 참여했으면 좋겠다.
John Dvorak

모든 유형의 변경 사항이 나타나거나 사람들이 계속 잘못된 알고리즘을 제출하도록 더 나은 예를 제공하십시오.
swish

답변:


4

GolfScript, 59 자

{32|}%"*"%.|(:w;{:x,),{:^[x>.1>]{.[^w=]\+}%{^x<\+w=},},},n*

물론 GolfScript는 문자열 조작에 좋습니다 !

GolfScript가 좋지 않은 것은 파일 I / O 또는 명령 줄 인수를 처리하는 것입니다. 따라서이 프로그램은 stdin을 통해 모든 입력을받을 것으로 예상합니다. 첫 번째 공백이 아닌 행은 대상 단어로 간주되고 나머지 행에는 사전이 포함되어야합니다. 유닉스 시스템에서는 다음과 같이이 코드를 실행할 수 있습니다.

(echo golf; cat /usr/share/dict/words) | ruby golfscript.rb similar.gs

내 Ubuntu Linux 상자에서 위 명령의 출력은 다음과 같습니다.

goff
wolf
gold
golfs
goof
gulf

모든 단어는 소문자로 변환되고 중복은 제거됩니다. 따라서, 샘플 출력과는 달리, 광산은 나열하지 않습니다 Wolfwolf별도. 귀하의 챌린지 설명을 바탕으로, 이것이 허용되는 것으로 간주합니다.

또한 코드는 상당히 무차별 한 접근 방식을 사용하기 때문에 실제로 느리고 후보 단어의 길이가 대상 단어의 길이와 일치하는지 확인하는 것과 같은 명백한 최적화도 사용하지 않습니다. ± 1 필터링되지 않은 전체 /usr/share/dict/words목록을 통해 ... 음 ... 완료되면 알려 드리겠습니다.

편집 : 좋습니다. 약 25 분이 걸렸지 만 완료되었습니다.


GolfScript가 문자열 조작 (및 GolfScript에서 문자열 조작 수행)에 얼마나 좋은지를 정확하게 나타내려면
PlasmaPower

6

Bash + coreutils, 99 바이트

@lambruscoAcido의 답변이 매우 다른 결과를 제공 한다는 질문을 완전히 오해 했거나 상당히 간단한 정규 표현식 응용 프로그램입니다.

for((i=0;i<${#1};i++)){
a=${1:0:i}
b=${1:i+1}
egrep -i "^($a$b|$a.$b|$a.${1:i}|$1.)$" $2
}|sort -u

산출:

$. / similar.sh 골프 / usr / share / dict / words
고프
금
골프
골프
멍청이
만
늑대
늑대
$ 

무엇을 설명해 주 ${a:b:c} 시겠습니까?
AL

1
@ n.1 변수의 위치 b에 있는 문자를 사용 c합니다a

2
@professorfish Close- 변수 c에서 위치 b(0 부터 시작)로 시작 하는 길이의 하위 문자열입니다 a. 부분 문자열 확장은 bash 매개 변수 확장
Digital Trauma

2
오 @DigitalTrauma 나는 내 배쉬 골프를 친다 그것을 계속 사용하더라도 잊어

3

파이썬 3, 291 자

매우 간단하고 그리 영리하지 않습니다. 그러나 큰 맛있는 발전기 얽힘과 최적화 된 속도 저하. 할당 된 계산 시간을 사용하지 않으려면 하시겠습니까?

from itertools import*
from sys import*
a=argv[1].lower()
r,l=range,len
n=l(a)
print('\n'.join((b for b in(s.strip()for s in open(argv[2]).readlines())if l(b)>n-2and b.lower()in(''.join(compress(a,(i!=j for j in r(n))))for i in r(n))or n==l(b)and sum(1for i in r(n)if a[i]!=b.lower()[i])<2)))

1
이러한 기능을 더 사용 l=len하고 r=range줄일 수 있습니다 .
TyrantWave

1

스칼라 - 403 130

[업데이트 됨] : 이전 솔루션에서도 순열 문자를 허용했기 때문에 완전히 업데이트되었습니다. 정규식이나 내장 도구를 사용하지 않습니다.

def f(x:String,d:List[String])={for{y<-d;c=(x zip y filter(t=>t._1!=t._2)length);n=y.length-x.length;if c<2&n==0|c==0&n==1}yield y

언 골프 드 :

def f(x:String, d:List[String]) = {
  for {
    y <- d
    c = (x zip y filter (t=>t._1!=t._2) length)  // #letter changes.
    n = y.length-x.length                        // Difference in word length.
    if c<2 & n==0 | c==0 & n==1
  } yield y
}

용법:

f("golf", io.Source.fromFile("/usr/share/dict/words").getLines.toList)

@DigitalTrauma 그 문제에 대한 예를 들어 주시겠습니까?
lambruscoAcido

나는 그것을 얻었다 : 나는 또한 문자의 모든 순열을 고려했다. 한숨-현실이 더 쉽습니다. 감사합니다 ...
lambruscoAcido

atechny한 글자를 바꾸지 않습니다. 이 솔루션은 질문과 관련이없는 작업을 수행합니다.
Konrad Borowski

+1. 외모가 ;-) 더 나은 지금 사양에 맞는처럼
디지털 외상

완전한 프로그램은 기능뿐만 아니라 훌륭 할 것입니다.
swish

1

Python, 174 자 :

빠르고 요점.

import re;from sys import*;w=argv[1]
print"\n".join(set(sum([re.findall(r"\b%s%s?[^'\n]?%s\b"%(w[:i],w[i],w[i+1:]),open(argv[2]).read(),re.I)for i in range(len(w))],[]))-{w})

예:

python similar.py golf /usr/share/dict/words

산출:

goof
gola
gulf
gold
gol
gowf
goli
Golo
Gulf
goaf
Wolf
Goll
Rolf
wolf
goff
Gold

OS X 단어 파일에 더 많은 항목이 있다고 가정합니다.


목록에는 단어 자체가 포함되어서는 안되며 아포스트로피도 무시하지 않아야합니다. UNIX 사전에는 golf'.
swish

아포스트로피를 무시한다는 것은 무슨 뜻입니까? 안내문을 다시 읽은 후에도 여전히 받고있는 내용이 표시되지 않습니다.
xleviator

사전에 코드를 실행하면 golf'인쇄됩니다.
swish

아, 나는 메시지를 잘못 읽었지만 지금 수정되었습니다.
xleviator

0

하스켈-219

import System.Environment
import Data.Char
u@(x:a)%w@(y:b)|x==y=a%b|1>0=1+minimum[a%w,u%b,a%b]
x%y=max(length x)$length y
main=do[w,d]<-getArgs;readFile d>>=mapM putStrLn.filter((==1).(%map toLower w).map toLower).words

0

리볼-213

set[i d]split system/script/args" "r:[skip i | i skip]repeat n length? i[append r compose[|(poke s: split i 1 n 'skip s)|(head remove at copy i n)]]foreach w read/lines to-file d[if all[w != i parse w r][print w]]


Ungolfed (일부 의견 포함) :

set [i d] split system/script/args " "

; build parse rule
r: [skip i | i skip]       ; RULE - one letter added (prefix and postfix)

; sub-rule for each letter in word
repeat n length? i [
    append r compose [
        | (poke s: split i 1 n 'skip s)     ; RULE - letter changed
        | (head remove at copy i n)         ; RULE - letter removed
    ]
]

foreach w read/lines to-file d [
    if all [w != i parse w r] [print w]
]

사용 예 (OS X Lion의 Rebol 3에서 테스트) :

$ rebol similar.reb golf /usr/share/dict/words
goaf
goff
gol
gola
Gold
gold
goli
Goll
Golo
goof
gowf
Gulf
gulf
Rolf
Wolf
wolf

다음은 parse유사한 단어를 골프 와 일치시키기 위해 만든 규칙입니다 .

[
    skip "golf"
  | "golf" skip
  | skip "o" "l" "f"
  | "olf"
  | "g" skip "l" "f"
  | "glf"
  | "g" "o" skip "f"
  | "gof"
  | "g" "o" "l" skip
  | "gol"
]

-1

파이썬 (103) :

f=lambda x:[a for a in open('/usr/share/dict/words')if len(x)==len(a)&sum(b!=c for b,c in zip(a,x))==1]

매우 효율적이라고 생각합니다. 또한, 나는 이것이 파이썬에서 얼마나 잘 골프를 쳤는지 좋아합니다.


캐릭터를 삭제하거나 추가하는 것에 대해 설명하지 않습니다.
swish
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.