Codegolf — Выберите Слово По Заданному Индексу В Заданной Строке.

  • Автор темы Liisvi
  • Обновлено
  • 22, Oct 2024
  • #1

В Windows, когда вы выполняете двойной щелчок по тексту, слово вокруг курсора в тексте будет выбрано.

(Эта функция имеет более сложные свойства, но их реализация для этой задачи не требуется.)

Например, пусть

 string    index     output    cursor position
abc def   2         abc       ab|c def
abc def   5         def       abc d|ef
abc abc   2         abc       ab|c abc
ab cd ef  4         cd        ab c|d ef
ab   cd   6         cd        ab   c|d
ab!cd     1         ab        a|b!cd
 
be your cursor in [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_] .

Затем, когда вы дважды щелкаете, подстрока \w will be selected.

Ввод/вывод

Вам будут предоставлены два входных параметра: строка и целое число.

Ваша задача — вернуть подстроку слова строки вокруг индекса, заданного целым числом.

Ваш курсор может быть правым до или правильно после символ в строке по указанному индексу.

Если вы используете правильно до, пожалуйста, укажите в своем ответе.

Технические характеристики (Спецификации)

Индекс гарантированный находиться внутри слова, чтобы не было таких крайних случаев, как (?<!\w)\w+(?!\w) or abc def| ghi .

Строка будет только содержат печатные символы ASCII (от U+0020 до U+007E).

Слово «слово» определяется регулярным выражением abc |def ghi , where def определяется abc de|f ghi , or "alphanumeric characters in ASCII including underscore".

Индекс может быть 1-индексным или 0-индексированный.

Если вы используете 0-индексацию, укажите это в своем ответе.

Тестовые случаи

Тестовые примеры имеют индекс 1, а курсор находится вправо. после указан индекс.

Позиция курсора предназначена только для демонстрационных целей и не требует вывода.

|

#код-гольф #строка

Liisvi


Рег
16 Feb, 2007

Тем
73

Постов
198

Баллов
583
  • 26, Oct 2024
  • #2

В, 10, 9 7 байт

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
(1)+¶(?<-1>.)*\b|\W.+

Попробуйте онлайн!

В этом ответе используется индексация на основе 1.

Это могло бы быть короче, если бы мы сделали именно то, что сказано в названии: «Выбирать слово вокруг данного индекса в строке». Мы могли бы сделать

 
 
 
 
 
 (n,w)=> _.From(w).Select((x,i)=>({i:i,x:x})).Split((i,v)=>v.x==" ").Where(a=>a.Min(i=>i.i)<=n-1&&a.Max(i=>i.i)>=n-2).First().Select(i=>i.x).Write("").match(/^\w*^\w*/)[0]
 

Который буквально выбирает слово, но, к сожалению, вообще не меняет вывод. Поэтому нам нужен небольшой обходной путь, чтобы заставить его работать: вырезать его в регистр, удалить остальной текст, а затем вставить регистр обратно.

Объяснение:

from string import* p='_'+printable[:62] def f(s,h,r=''): while s[h]in p and h>-1:h-=1 while h+1<len(s)and s[h]in p:h+=1;r+=s[h] return r ||answer||

С, 104 байта

PREG_SPLIT_OFFSET_CAPTURE

Ожидается, что входные данные на стандартный ввод будут индексом, отсчитываемым от 0, за которым следует один пробел или новая строка, а затем строка. Максимальная длина слова — 99 символов. Например.:

4 ||answer||

C (gcc), 94 байта

function f($s,$p){foreach(preg_split('#\W+#',$s,-1,4)as$m)if($m[1]+strlen($m[0])>=$p)return$m[0];}

С нулевым индексом определяет функцию, принимающую индекс, а затем строку.

 

ArturowtfaAr51


Рег
25 Oct, 2024

Тем
79

Постов
211

Баллов
606
  • 26, Oct 2024
  • #3

Ретина, 22 года

PS C:\Tools\Scripts\golfing> .\select-the-word-around-the-index.ps1 2 'This!test' This PS C:\Tools\Scripts\golfing> .\select-the-word-around-the-index.ps1 5 'This!test' test

Попробуйте онлайн! или проверить все тестовые случаи. Обычная программа занимает позицию курсора в унарном формате, за которой следует перевод строки, а затем строка. Набор тестов содержит дополнительный код для запуска в построчном режиме и использует -join as a delimiter, and it uses decimal, for convenience.

Использует балансирующие группы для определения позиции курсора, а затем возвращается к границе слова. Удаляет текст до слова, а затем после слова.

 

CinkAlkal


Рег
01 Sep, 2011

Тем
76

Постов
229

Баллов
679
  • 26, Oct 2024
  • #5

JavaScript (V8), 44 байта

$a

Попробуйте онлайн!

Это длиннее, чем существующее решение JS, но я на самом деле не понимаю, какой подход оно использует, и написал это до того, как увидел это решение. Надеюсь, это достаточно необычно, чтобы быть интересным :P

Объяснение кода, чтобы вас не постигла та же участь.

$i=$a-- ||answer||

С, 115 байт

Функция ++$a requires the string and index (1-indexed) as parameters and prints the result to stdout. Cursor should be after the specified character.

$n ||answer||

JavaScript (ES6), 57 байт

$a

Просто разрезает строку в точке курсора (которая находится перед символом с индексом 0, что работает так же, как и после символа с индексом 1), затем извлекает и объединяет фрагменты соседних слов. Even возвращает разумный результат, когда курсор находится в начале, конце или где-то рядом со словом.

 

Denis333x


Рег
03 Dec, 2019

Тем
79

Постов
211

Баллов
606
  • 26, Oct 2024
  • #6

Java 8, 86 78 байт

param($a,$n)for(;$n[++$a]-match'\w'){}$i=$a--;for(;$n[--$a]-match'\w'-and$a-ge0){}-join$n[++$a..--$i]

Ungolfed с тестовыми примерами:

'\w+' % Push string to be used as regex pattern 5B#XX % Take input string implicitly. Apply regex. Push matches and ending indices i> % Take input number. Compare with obtained ending indices. Gives true for % ending indices that exceed the input number ) % Use as logical index to select the corresponding matches 1) % Select the first match. Implicitly display

Разбивает строку на небуквенно-цифровые символы, а затем продолжает вычитать длину каждой подстроки плюс 1 из указанной позиции, пока она не станет отрицательной. Поскольку любые повторяющиеся символы, не являющиеся буквами и цифрами, представляются как пустая строка, логика вычитания значительно упрощается.

Этот код тщательно не тестировался, поэтому мне хотелось бы посмотреть, сможет ли кто-нибудь его взломать. Кроме того, учитывая, что это код Java, почему это не самый длинный ответ здесь? :П

 

Creaphype2


Рег
25 Oct, 2024

Тем
67

Постов
186

Баллов
521
  • 26, Oct 2024
  • #7

Рубин, 41 31 байт

Попробуйте онлайн!

-10 байт от @MartinEnder

'\w+'5B#XXi>)1) ||answer||

Пайк, 19 байт

e€ØW For each element, is it a word character? Ä Take the cumulative sum ¬ of the negations ÷Ɗ and divide by the original Booleans. = For each value in the result, is it equal to ị@¥ the one at the index? xð Filter the string to truthy positions.

Попробуйте здесь!

Использование xðe€ØW¬Ä÷Ɗ=ị@¥ as a no-op to make sure the first input is placed correctly

Ż Prepend a zero as a buffer between the first and last words, ṙ then rotate left by the index. œpƊ Partition that result around € ¬ elements which are not e ØW word characters, .ị then take the last and first slices and smash-print them together. ||answer||

Питон 2, 70 66 байт

Żṙe€ØW¬œpƊ.ị

Разбивает строку с помощью разделителей, не являющихся словами, сначала по исходной строке до индекса курсора, затем по строке, начинающейся с индекса курсора. Возвращает последний элемент левого разделения плюс первый элемент правого разделения.

Спасибо Leaky Nun за экономию 4 байт!

 

Oleg10


Рег
20 Oct, 2005

Тем
83

Постов
211

Баллов
656
  • 26, Oct 2024
  • #8
f←{m←⎕A,⎕a,⎕D,'_'⋄↑v⊂⍨m∊⍨v←⍵↓⍨¯1+⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺} 2 f 'abc def' abc 5 f 'abc def' def 2 f 'abc abc' abc 4 f 'ab cd ef' cd 1 f 'ab!cd' ab 6 f 'ab cd' cd

Кложур, 92 байта {m←⎕A,⎕a,⎕D,'_'⋄↑v⊂⍨m∊⍨v←⍵↓⍨¯1+⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺} into two strings. Then for these strings find occurrences of ->s,n{s[/.{#{n}}\w+/][/\w+$/]} Сначала разбивает входную строку по позиции

и верните их в виде списка. Затем объедините последний элемент первого списка и первый элемент второго списка. https://ideone.com/Dk2FIs

Посмотрите онлайн:

 

Johnny_Puh


Рег
22 Nov, 2013

Тем
67

Постов
190

Баллов
565
  • 26, Oct 2024
  • #9
->\b{ } # Anonymous code block that takes a number &{ } # And returns another code block that first ,m:g/<<\w+>>/ # Finds the first word in the input *.to>b # Where the start is after the number f(n)(string) ->\b{&{first *.to>b,m:g/<<\w+>>/}} ð« # Append a space to the (implicit) input-String ._ # Rotate this string the (implicit) input-integer amount of times # towards the left D # Duplicate this string žjм # Remove [a-zA-Z0-9_] from the string S¡ # Split the rotated string by each of the remaining characters Á # Rotate the resulting list once towards the right 2£J # And only leave the first two items, joined together # (which is output implicitly) JavaScript (ES6), 52 байта

 

Yunusov


Рег
04 Mar, 2011

Тем
78

Постов
211

Баллов
621
  • 26, Oct 2024
  • #10

Луа, 71 67 байт

Ого, Lua — не самое длинное решение! Все еще на один байт отстает от Python, но не знаю, как это исправить. Индексы отсчитываются от 1. ð«._DžjмS¡Á2£J , saved 4 bytes

function(s,n){s.replace(/\w*/g,function(x,y){y<n?s=x:0});alert(s)}

Спасибо @LeakyNun, который напомнил мне о существовании

Старый 71 s=>n=>s.replace(/\w*/g,(x,y)=>y<n?s=x:0)&&s

[^%a_]*

Примечание: объяснения по-прежнему основаны на этом, поскольку оно также применимо и к новому, но содержит некоторую дополнительную информацию о

Объяснение g:sub(h+1):gmatch"[%a_]*"()) and g:sub(1,h):gmatch"[%a_]*$"() Сначала мы распаковываем аргументы в gmatch

0..n

потому что они короче

Затем мы создаем наш вывод, который представляет собой объединение частей до курсора и после него.

:gmatch"[%a_]*$"

Первая часть строки string.gmatch

g:sub(1,h)

Мы хотим найти слово в конце этого слова, поэтому используем функцию g,h=... times the character set of alphabet+underscore at the end of the string. arg[x] Этот шаблон соответствует

h

возвращает итератор в своем списке совпадений в виде функции (используя принцип замыкания), поэтому мы выполняем его один раз, чтобы получить первую часть нашего слова

g

Вторую часть нашего слова получаем таким же образом g,h=...print(g:sub(1,h):gmatch"[%a_]*$"()..g:sub(h+1):gmatch"[%a_]*"()) ), as it will be the match returned by the iterator when it's called the first time.

Единственная разница в том, что нам не нужно указывать, что мы хотим сопоставить в начале строки (используя

 

Gbcfkf


Рег
04 Apr, 2011

Тем
91

Постов
200

Баллов
675
  • 26, Oct 2024
  • #11
gmatch

JavaScript (ES 6), 4342 байта

g,h=...print(g:sub(1,h):match"[%a_]*$"..g:sub(h+1):match("[%a_]+")) ||answer||

JavaScript (ES 3), 65 байт, 14 05AB1E

string.match

байты Порт@АндерсКасеорг.

Ответ Пита

1-индексирован, как и тестовые примеры задачи. Попробуйте онлайн или.

проверить все тестовые случаи

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> ||answer||

Объяснение:Перл 6

input[type="number"] { width: 3em; } table { border-spacing: 0.5em 0; border-collapse: separate; margin: 0 -0.5em ; } td, input { font-family: monospace; } th { text-align: left; } tbody { padding: 1em 0; } pre { margin: 0; }

, 34 байта

Попробуйте онлайн! const F = (s,n) => RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2] class Test extends React.Component { constructor(props) { super(props); const input = props.input || ''; const index = props.index || 0; this.state = { input, index, valid: /\w/.test(input), }; } onInput = () => { const input = this.refs.input.value; const index = Math.min(+this.refs.index.value, input.length); this.setState({ input, index, valid: /\w/.test(input), }); } render() { const {input, index, valid} = this.state; return ( <tr> <td>{ this.props.children }</td> <td> <input ref="input" type="text" onInput={this.onInput} value={input} /> <input ref="index" type="number" onInput={this.onInput} min="1" max={input.length} value={index} /> </td> {valid && [ <td>{F(input, index)}</td>, <td><pre>{input.slice(0, index)}|{input.slice(index)}</pre></td>, ]} </tr> ); } } class TestList extends React.Component { constructor(props) { super(props); this.tid = 0; this.state = { tests: (props.tests || []).map(test => Object.assign({ key: this.tid++ }, test)), }; } addTest = () => { this.setState({ tests: [...this.state.tests, { key: this.tid++ }], }); } removeTest = key => { this.setState({ tests: this.state.tests.filter(test => test.key !== key), }); } render() { return ( <div> <table> <thead> <th/> <th>Test</th> <th>Output</th> <th>Diagram</th> </thead> <tbody> { this.state.tests.map(test => ( <Test key={test.key} input={test.input} index={test.index}> <button onClick={() => this.removeTest(test.key)} style={{ verticalAlign: 'middle', }}>-</button> </Test> )) } </tbody> <tfoot> <td/> <td> <button onClick={this.addTest} style={{ width: '100%', }}>Add test case</button> </td> </tfoot> </table> </div> ); } } ReactDOM.render(<TestList tests={[ { input: 'abc def', index: 2 }, { input: 'abc def', index: 5 }, { input: 'abc abc', index: 2 }, { input: 'ab cd ef', index: 4 }, { input: 'ab cd', index: 6 }, { input: 'ab!cd', index: 1 }, ]} />, document.body); .

Анонимный кодовый блок, который каррирует входные данные, например

(s,n)=>RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2] ||answer||

Объяснение:Руби

"\w+"

, 30 байт

Попробуйте онлайн!

Другой подход, всего на 1 байт короче и 3 года спустя. Почему нет?

 

Gordje


Рег
18 Jul, 2008

Тем
58

Постов
212

Баллов
512
  • 26, Oct 2024
  • #12
k

APL(NARS), 58 символов, 116 байт

(fn[x k](let[[u i](map #(re-seq #"\w+"(apply str %))(split-at k x))](str(last u)(nth i 0)))) ||answer||

⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺ найти, где начинается строка... Как использовать и тестировать:Желе

import re f=lambda x,y,r=re.split:r('\W',x[:y])[-1]+r('\W',x[y:])[0]

, 12 байт

Попробуйте онлайн! Порт.

# ) - first where c - input.split() ml - map(len, ^) i< - ^[:i] i+ - ^+[i] s - sum(^) lt - len(^)-2

Ответ Андерса Касеорга на Пите

Оригинал:Желе

Q;

, 14 байт

#Q;cjmli<i+s)lttjR@ ||answer||

Попробуйте онлайн!МАТЛ

->s,i{s[/\w*(?<=^.{#{i}})\w*/]}

, 16 15 байт

Курсор имеет индекс 1 и находится после символа (как в тестовых примерах). Попробуйте онлайн! Или.

class Indexer { public static String f(String s, int p) { for(String t : s.split("\\W")) if((p -= t.length()+1) < 0) return t; return ""; } public static void main(String[] args) { System.out.println(f("abc def",2)); System.out.println(f("abc def",5)); System.out.println(f("abc abc",2)); System.out.println(f("ab cd ef",4)); System.out.println(f("ab cd",6)); System.out.println(f("ab!cd",1)); } } ||answer||

проверить все тестовые случаи

(s,p)->{for(String t:s.split("\\W"))if((p-=t.length()+1)<0)return t;return"";}

PowerShell v3+, 103 101 байт

Какое-то глупое решение, но подход другой, чем у других. f=(s,n)=>s.slice(0,n).match(/\w*$/)+s.slice(n).match(/\w*/) as the 0-based index of the string f(char*p,int n){char*s=p+n;for(;s>=p&&isalnum(*s)+(*s==95);--s);for(p=s+1;*p&&isalnum(*p)+(*p==95);putchar(*p++));} . Затем мы находим границы нашего слова. Хотя мы еще не достигли конца строки и/или все еще сопоставляем символы слова, мы f() . Then, because of fenceposting, we set (i,x)=> take i (number) and x (string) RegExp(`...${i}...`) construct a regex with i in it .exec(x)[0] return the first result of that regex on the string \w*(?<=.{i}) constructed regex \w* match an entire word (?<= ) if the end of the word comes after .{i} at least i characters . Далее ползем назад, уменьшаясь (i,x)=>RegExp(`\\w*(?<=.{${i}})`).exec(x)[0] until it's either +e=:.<+QbE"\W"3h Q first input (string) + b plus newline .< E rotate left by second input (number) : "\W"3 split on regex \W, non-word characters = assign to Q e last element + hQ plus first element или мы нажимаем на символ, не являющийся словом. Затем мы разрезаем входную строку на основе этих двух границ (с некоторым увеличением/уменьшением для учета OBOE) и \ it together to produce the result.

Примеры

f(n,p)char*p;{for(p+=n-1;isalnum(*p)|*p==95&&n--;--p);for(;isalnum(*++p)|*p==95;putchar(*p));} ||answer||

PHP, 98 байт

2 abc def
  • разбивает строку на символы, не являющиеся словами, запоминая их позицию ( p[99];i,d;main(l){for(scanf("%d",&i);scanf("%[^a-zA-Z0-9_]%[a-zA-Z0-9_]%n",&d,&p,&l),i>l;i-=l);puts(p);} == À| " Jump the position of argument 1 diw " (d)elete (i)nside this (w)ord. V " Select this line p " And replace it with the word we just deleted ), циклически перебирает слова, пока не будет достигнута позиция.
  • Строки PHP имеют индекс 0, курсор находится перед символом, но может находиться до или после слова.
 

Troniq


Рег
04 Oct, 2014

Тем
70

Постов
217

Баллов
607
  • 26, Oct 2024
  • #13

Питон 3, 112 140 байт

À|viw

0-индексированный.

Выполняет поиск назад к первому буквенно-цифровому символу индекса, а затем переходит к последнему буквенно-цифровому символу после индекса. Вероятно, есть более разумный способ сделать это.

Попробуйте это

 

Wewiqwnrig


Рег
27 Nov, 2011

Тем
71

Постов
196

Баллов
571
  • 26, Oct 2024
  • #14

Javascript (с использованием внешней библиотеки) (168 байт)

À|diwVp

Ссылка на библиотеку:https://github.com/mvegh1/Enumerable/blob/master/linq.js

Объяснение кода: Библиотека принимает строку, которая преобразуется в массив символов. Он сопоставляется с объектом, хранящим индекс и символ. Последовательность разбивается на подпоследовательности при каждом появлении " ". Подпоследовательности фильтруются путем проверки, содержится ли индекс курсора в минимальном и максимальном индексе подпоследовательности. Затем берем первую подпоследовательность. Затем мы преобразуемся обратно в массив символов. Затем мы объединяем все символы с помощью «» в качестве разделителя. Затем мы проверяем регулярное выражение слова. Затем берем первую спичку.

 

Farysth


Рег
12 Mar, 2016

Тем
87

Постов
197

Баллов
672
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно