สลับตัวอักษรหนึ่งตัว


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 หรืออัลกอริทึมที่คล้ายกัน สิ่งที่เกี่ยวกับการไม่ได้คิดค้นที่นี่หรือแบ็คดอร์ที่เห็นได้ชัดว่าผู้ขายใส่เข้าไปในภาษา (คุณไม่ได้พิสูจน์สิ่งเหล่านั้น แต่ไม่ได้พูดคุยกับเจ้านายของคุณ) ดังนั้นหากคุณต้องการระยะทางคุณจะต้องดำเนินการด้วยตัวเอง

คุณมีอิสระในการใช้ภาษาใด ๆ แม้ว่าจะมีการ์ดเจาะรู แต่ บริษัท ก็สามารถเข้าถึงภาษาการเขียนโปรแกรมที่ทันสมัยที่สุดเช่นCobol Ruby หรือ Haskell หรืออะไรก็ตามที่คุณต้องการ พวกเขามี GolfScript ถ้าคุณคิดว่ามันดีสำหรับการจัดการสตริง (ฉันไม่รู้บางที ... )

ผู้ชนะได้รับ 15 คะแนนชื่อเสียงจากฉันและอาจเป็นจำนวนมากจากชุมชน คำตอบที่ดีอื่น ๆ จะได้รับ 10 คะแนนและคะแนนจากชุมชนเช่นกัน คุณได้ยินมาว่าคะแนนนั้นไร้ค่า แต่มีแนวโน้มมากที่สุดที่พวกเขาจะเข้ามาแทนที่ฟันกรามในปี 2593 ซึ่งไม่ได้รับการยืนยัน แต่เป็นความคิดที่ดีที่จะได้รับคะแนนอย่างไรก็ตาม


6
เราไม่ควร "ใช้การใช้งานระยะทาง Levenshtein ในตัวหรือภายนอกหรืออัลกอริทึมที่คล้ายกัน" มีวิธีแก้ปัญหา Mathematica 30 ตัวอักษร
Michael Stern

@MichaelStern และงูหลามสั้นที่คล้ายกันโดยใช้การจับคู่แบบเลือนของไลบรารี regex นี้
Martin Ender

2
เกือบจะเหมือนกับcodegolf.stackexchange.com/questions/6939/...
Howard

"เช่น Ruby หรือ Haskell" - โอเคฉันเข้าใจแล้วคุณต้องการให้ฉันเข้าร่วม
John Dvorak

โปรดระบุตัวอย่างที่ดีกว่าเพื่อให้การเปลี่ยนแปลงทุกประเภทปรากฏขึ้นหรือผู้คนจะส่งอัลกอริทึมที่ไม่ถูกต้อง
หวด

คำตอบ:


4

GolfScript, 59 ตัวอักษร

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

แน่นอนว่า GolfScript นั้นยอดเยี่ยมสำหรับการจัดการสตริง!

GolfScript สิ่งที่ไม่ดีในการจัดการไฟล์ I / O หรืออาร์กิวเมนต์บรรทัดคำสั่ง ดังนั้นโปรแกรมนี้คาดว่าจะได้รับการป้อนข้อมูลทั้งหมดผ่าน stdin: บรรทัดแรกที่ไม่ว่างเปล่าจะถูกนำมาเป็นคำเป้าหมายในขณะที่บรรทัดที่เหลือควรมีพจนานุกรม ในระบบ Unixish คุณสามารถเรียกใช้รหัสนี้เช่นกับ:

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

บนกล่อง Ubuntu Linux ของฉันผลลัพธ์ของคำสั่งด้านบนคือ:

goff
wolf
gold
golfs
goof
gulf

โปรดทราบว่าคำทั้งหมดจะถูกแปลงเป็นตัวพิมพ์เล็กและรายการที่ซ้ำจะถูกลบออก ดังนั้นซึ่งแตกต่างจากผลลัพธ์ตัวอย่างของคุณเหมืองไม่ได้แสดงรายการWolfและwolfแยก จากคำอธิบายการท้าทายของคุณฉันถือว่านี่เป็นสิ่งที่ยอมรับได้

ยิ่งไปกว่านั้นโค้ดช้ามากเนื่องจากใช้วิธีการเดรัจฉานอย่างแรงและไม่ได้ใช้การปรับให้เหมาะสมที่ชัดเจนเช่นการตรวจสอบว่าความยาวของคำที่เหมาะสมกับคำที่เป็นเป้าหมาย± 1 ยังคงอยู่ ผ่าน/usr/share/dict/wordsรายการที่ไม่มีการกรองใน ... อืม ... ฉันจะบอกให้คุณรู้เมื่อมันเสร็จสิ้นแล้ว OK

แก้ไข:ตกลงใช้เวลาประมาณ 25 นาที แต่ก็เสร็จสิ้น


+1 สำหรับการแสดงที่แม่นยำว่า GolfScript นั้นดีเพียงใดสำหรับการจัดการสตริง (และการจัดการสตริงใน GolfScript)
PlasmaPower

6

Bash + coreutils, 99 ไบต์

ทั้งฉันเข้าใจผิดโดยสิ้นเชิงคำถาม ( คำตอบของ @ lambruscoAcido ให้ผลลัพธ์ที่แตกต่างกันมาก ) หรือนี่เป็นแอปพลิเคชัน regexp ตรงไปตรงมา:

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 golf / usr / share / dict / words
กอฟฟ์
ทอง
กอล์ฟ
โรงแรมพร้อมสนามกอล์ฟ
คนโง่
อ่าว
หมาป่า
หมาป่า
$ 

คุณช่วยอธิบายสิ่งที่${a:b:c} ทำได้ไหม
อัล

1
@ n.1 มันต้องใช้ตัวอักษรที่ตำแหน่งbไปcในตัวแปรa

2
@professorfish ปิด - อักขระย่อยของระยะเวลาในcการเริ่มต้นที่ตำแหน่งb(zero-based) aจากตัวแปร การขยายซับสตริงเป็นหนึ่งในการขยายพารามิเตอร์ bash
Digital Trauma

2
@DigitalTrauma โอ้ฉันลืมแม้ว่าฉันจะใช้มันต่อไปใน Bash golfs ของฉัน

3

Python 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

[อัปเดต]: อัปเดตอย่างสมบูรณ์เพราะโซลูชั่นแบบเดิมอนุญาตให้ใช้กับตัวอักษรที่เปลี่ยนแปลงได้ ห้ามใช้ regex หรือเครื่องมือบิลด์อินใด ๆ

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

Ungolfed:

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 ดูเหมือนว่าจะเหมาะกับสเป็กที่ดีกว่าตอนนี้ ;-)
Digital Trauma

โปรแกรมที่สมบูรณ์จะดีไม่ใช่แค่ฟังก์ชั่น
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 มีรายการมากกว่านี้


รายการไม่ควรมีคำว่าตัวเองและยังไม่ละเว้น apostrophes: กับ UNIX golf'พจนานุกรมก็ยังมี
swish

คุณหมายถึงอะไรโดยไม่สนใจอะพอสโทรฟี หลังจากอ่านพรอมต์อีกครั้งฉันยังไม่เห็นสิ่งที่คุณได้รับ
xleviator

ถ้าฉันเรียกใช้รหัสของคุณในพจนานุกรมด้วยgolf'มันจะถูกพิมพ์
swish

อ่าฉันอ่านพรอมต์ผิด แต่ตอนนี้ได้รับการแก้ไขแล้ว
xleviator

0

Haskell - 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

Rebol - 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]
]

ตัวอย่างการใช้งาน (ทดสอบใน Rebol 3 บน OS X Lion):

$ 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

Python (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.