Указатели, указатели, указатели!


46

Введение

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

Возьмите этот пример на Ideone:

Main.java:12: error: ';' expected
    Invalid Java!
                ^

Обратите внимание, каретка показывает, где находится неверный код?

Вызов

Ваша задача состоит в : заданное число N и строка S , поместите указатель на N - й символ в S .

Примеры

Вход :2, "Lorem ipsum, dollar sit amet."

Выход :

Lorem ipsum, dollar sit amet.
 ^

правила

  • Вход получен через STDIN или функциональные параметры
  • Вывод выводится на консоль или returnредактируется
  • Завершающие новые строки, пробелы и т. Д. Допускаются в выводе
  • Символ указателя должен быть символом ^ и должен находиться на новой строке.
  • Это код гольф, поэтому самый короткий ответ выигрывает. Удачи!

16
Я чувствую, что это чрезвычайно простая проблема, поэтому я не уверен, что она будет воспринята слишком хорошо. Возможно, вы захотите попробовать песочницу, как только у вас будет достаточно повторений.
FryAmTheEggman

6
Я думаю, что это могло бы быть немного интереснее, если бы на входе было несколько строк, так что вам пришлось вставлять новую строку, пробелы и карат в правильных положениях. Честно говоря, в спецификации на самом деле не говорится, что это будет одна строка, но я думаю, что принудительное выполнение этого теперь приведет к несправедливому аннулированию нескольких ответов, поскольку нет примера, демонстрирующего это.
Geobits

3
Как я уже сказал, на этой кошке, вероятно, нет сумок. Изменения в правилах после публикации действительных ответов обычно не работают должным образом. Живи и учись;)
Geobits

1
@ SohamChowdhury Я просто притворюсь, что это было сделано намеренно;) Вы хотите, чтобы я это исправил?
monkeyonkeyboard

9
Хотя это может быть очень просто, вы, безусловно, хорошо справились с первой задачей! У вас есть + 16 / -0 голосов, 1300 просмотров и 28 ответов (на момент написания статьи), и вы составили список Горячих сетевых вопросов. Хорошая работа!
Алекс А.

Ответы:


36

С 33

Если разрешена только функция, то даже c может конкурировать.

(Для записи, 2 байта были сохранены благодаря @Cool Guy. Комментарий был неожиданно испарен.)

Еще 1 символ спасен thx @Mig

f(a,c){printf("%s\n%*c",a,c,94);}

19
С всегда может соревноваться, просто не всегда побеждает. ;)
Алекс А.

3
@AlexA. <shrug> выглядит для меня как выигрыш ;-)
Digital Trauma

3
Сохранить 1 символ:f(a,c){printf("%s\n%*c",a,c,94);}
Майкл М.

Если бы я был циничным человеком, я бы сказал, что это примерно в 4 раза больше, чем самый короткий ответ на языке игры в гольф. Который о бизнесе как обычно. ;) Это умно, хотя. Я думаю, что видел *вариант в строке формата раньше, но полностью забыл об этом. Может пригодиться для решения некоторых задач ascii art в будущем.
Рето Коради

35

Brainf * ck - 133 байта

+++++>>+>>+++>>+++++++++<<<<<<[[->++++++++++<]>>]<++++<<++<<<<--<,>[->+<<->]>>>,<<[->>-<<]<<[->>>>++++++++++<<<<]>>+[,.]>.>[->.<]>>>.

Ожидается ввод, [0-9]{2}.*например, "02Hello world !!!" будет производить

Привет, мир!!!
 ^

Добро пожаловать в программирование головоломок и Code Golf! Это отличный первый пост, отличная работа! : D
Алекс А.

Проблема в том, что никто не знает, является ли этот код допустимым, не говоря уже о том, чтобы решить проблему :)
Simon

Да, я думаю, что здесь есть ошибка. Каретка должна быть eв примере. По стоимости 1 байт это можно исправить, добавив -перед[->.<]
FryAmTheEggman

@FryAmTheEggman вы правы - смотрите редактирование. Изначально он был у меня под e, как сейчас, но я запутался, используя две IDE с разными шрифтами.
sudo rm -rf slash

25

Машинный код IA-32, 24 байта

HexDump:

66 b8 5e 00 42 38 22 75 fb 66 c7 02 0d 0a 42 42
c6 02 20 e2 fa 89 02 c3

Это функция (с использованием fastcallсоглашения MS ), которая обновляет строку на месте:

__declspec(naked) void __fastcall carrot(int n, char* s)

Код сборки:

    mov ax, '^'; // ah = 0, al = '^'

mystrlen:
    inc edx;
    cmp [edx], ah;
    jne mystrlen;

    mov word ptr [edx], '\r\n'; // append a newline
    inc edx;

mymemset:
    inc edx;
    mov byte ptr [edx], ' ';
    loop mymemset;

    mov [edx], eax; // append a caret and terminate the string
    ret;

Он использует WORDразмерные (16-битные) данные в нескольких местах. Это имеет штраф (1-байтовый префикс) в 32-битном коде, но в любом случае делает код меньше - использование 32-битных данных приведет к добавлению двух нулевых байтов в код!

В конце он записывает 4 байта ( eax) вместо 2 байтов ( ax) - таким образом, код становится меньше, и 2 лишних байта мусора идут после завершения строки, поэтому никто их не замечает.

Использование:

int main()
{
    char s[100] = "Lorem ipsum, euro sit amet.";
    carrot(2, s); // credit to Digital Trauma for the name
    puts(s);
}

1
Инструкция 66 b8 5e 00перемещается 0x5eк al, а не к ah, и к нулю ahвместо al, поэтому ваш комментарий в коде сборки вводит в заблуждение.
Руслан

@ Руслан Спасибо! Исправлена. Это был остаток от предыдущей версии.
Анатолий

Почему nakedтам? И почему это первое, что я увидел?
caird coinheringaahing

Именно Microsoft решила сделать это naked: msdn.microsoft.com/en-us/library/h5w10wxs.aspx
anatolyg

20

Пиф , 8

zp\^*tQd

Это решение больше не работает, так как коммит после того, с которым я связался в качестве имени языка, изменился pна arity 1. Есть несколько других способов достижения того же результата в Pyth, которые до сих пор работают, например zp+*dQ\^.

Если строка нуждается в кавычках, добавление vв начало кода работает. Если он должен быть разделен запятыми, он занимает до 10 байтов:

eQp\^*dthQ

Я думаю, что это самый короткий пока. Отлично сработано.
monkeyonkeyboard

Алгоритм кажется мне неправильным, я думаю, ^что всегда будет под первым символом. И, кстати, входные параметры передаются в неправильном порядке онлайн-интерпретатору (поэтому он не выполняется).
Джим

1
@Jim В этом ответе использовалась более старая версия pyth, в которой pбыла арность 1. Это привело к тому, что сначала печаталась первая строка вывода, а затем каретка на следующей строке с пробелами. Теперь вы можете сделать z+*dQ\^для более короткой оценки, но с завершающей новой строкой, или добавить pперед, +чтобы удалить его. Я не уверен, что делать здесь, так как люди проголосовали за эту версию ответа, я думаю, что я попытаюсь найти версию, над которой он работал.
FryAmTheEggman

16

T-SQL, 90

Хотя это довольно простой вопрос, всегда интересно пробовать их на языках, которые на самом деле не склонны поддерживать их или играть в гольф в этом отношении.

Этот ответ почти гарантированно будет самым длинным.

Это создает встроенную табличную функцию для SQL Server, которая принимает @n и @ в качестве параметров и возвращает результаты в виде столбца. Возврат каретки значителен, иначе мне нужно было бы использовать char (13).

CREATE FUNCTION G(@N INT,@ VARCHAR(MAX))RETURNS TABLE RETURN SELECT @+'
'+SPACE(@n-1)+'^'R

Используется следующим образом

SELECT R 
FROM (VALUES
    (1,'This is test 1'),
    (2,'This is test 2'),
    (3,'This is test 3'),
    (4,'This is test 4'),
    (5,'This is test 5')
    )T(n,S)
    CROSS APPLY G(n,S)

И возвращает

R
---------------
This is test 1
^
This is test 2
 ^
This is test 3
  ^
This is test 4
   ^
This is test 5
    ^

Очень креативное использование языка, не предназначенного для игры в гольф;) +1
monkeyonkeyboard

14

Python, 27

lambda n,s:s+'\n%%%dc'%n%94

Это использует два уровня форматирования строки.

И вот 25-байтовое решение, частично украденное из ответа feersum (с обратным порядком аргументов):

lambda*p:'%s\n%%%dc'%p%94

12

Баш, 27

printf %s\\n%$[$1-1]s^ "$2"

Выход

$ ./carrot.sh 2 "Lorem ipsum, dollar sit amet."
Lorem ipsum, dollar sit amet.
 ^$ 

Морковь? Кроме того, что доллар в конце?
Scimonster

7
Доллар, похоже, подсказывает снаряд.
М.Херцкамп

3
@ Scimonster Carrot была моей попыткой пошутить - см. Мой ответ на вопрос . И да, $в конце подсказка оболочки. Вопрос указывает, что завершающие символы новой строки разрешены, но не говорит, что они необходимы.
Цифровая травма

10

Python, 29

lambda n,s:s+'\n'+' '*~-n+'^'

Объединяет строку, символ новой строки, n-1пробелы и a ^.


2
Если бы rjustне было так долго ...
Sp3000

10
Ах, головастик.
user253751 10.06.15

10

Сед, 16

2y/1/ /;2s/ $/^/

Это что-то вроде тестового примера этого мета-ответа . В частности, я требую, чтобы число N вводилось в одинарном формате. Например, для каретки в положении 2 вход для N будет 11. Также строго не указано, какой порядок должен быть S и N , поэтому здесь S идет первым, за которым следует унарный N в новой строке через STDIN.

Выход:

$ { echo "Lorem ipsum, dollar sit amet."; echo 11; } | sed '2y/1/ /;2s/ $/^/'
Lorem ipsum, dollar sit amet.
 ^
$

1
2y/1/ /;2s/ $/^/
manatwork

@ Manatwork Хороший звонок!
Цифровая травма

9

JavaScript (ES6): 63 62 56 52 32 байта

Спасибо nderscore за значительное уменьшение размера кода.

p=(a,b)=>b+`\n${' '.repeat(a)}^`

Версия, которая работает в нескольких браузерах (47 байт):

p=function(a,b){return b+`\n${' '.repeat(a)}^`}

1. В вопросе используется индексирование на основе 1, так что вам нужно Array(a-1). 2. Анонимные функции разрешены по умолчанию, поэтому вам не нужно point=. 3. Для версии ES6 вы можете избавиться от returnоператора и скобок. Просто используйте (a,b)=>b+"\n"+Array(a-1).join(" ")+" ^".
Деннис

1
33 байта: (заменить \nна новую p=(a,b)=>b+`\n${' '.repeat(a-1)}^`
строку

@dennis Индексация отлично работает для меня: i.stack.imgur.com/Tdejc.png
adroitwhiz

@Dennis Array(1).join(' ')приводит к пустой строке :)
nderscore

@nderscore Я не могу найти способ использовать фактическую новую строку, если она не вызывает разрыв строки во фрагменте кода, и индексация следует приведенному примеру: i.stack.imgur.com/Tdejc.png
adroitwhiz

7

CJam, 9 байт

q~N@(S*'^

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

Как это устроено

q~  e# Read the input from STDIN and interpret it.
    e# This pushes the integer and the string on the stack.
N@  e# Push a linefeed an rotate the integer on top of it.
(S* e# Subtract 1 and push a string consisting of that many spaces.
'^  e# Push a caret.

6

Python, 29

Вот более забавный способ сделать это в 29:

lambda*p:'%s\n%*s'%(p+('^',))

Пример использования:

>>> f=lambda*p:'%s\n%*s'%(p+('^',))
>>> print f('lorem',5)
lorem
    ^

5

TI-BASIC, 10 (?) Байтов

Disp Ans
Output(3,N,"^

Вводится в переменной N, как задает вопрос, но вы не можете использовать букву var S в качестве строки. Вместо этого, он принимает строку ввода от Ans, так , чтобы запустить пример в OP: 2->N:"Lorem ipsum, dollar sit amet.":prgm<program name>.

Я знаю, что это, вероятно, не считается, поскольку каждый разделенный двоеточиями сегмент технически является отдельным утверждением; вот 46-байтовая программа, которая принимает входные данные как N "S"( 2 "Lorem ipsum, dollar sit amet.")

Input Str1
2+inString(Str1," 
//^there's a space after the quote
Disp sub(Str1,Ans,length(Str1)-Ans
Output(4,expr(sub(Str1,1,1)),"^

Оба из них предполагают, что экран был очищен перед запуском.


Вы бы лучше взяли ввод от Input для числа и Ans для строки.
lirtosiast

Первый также не работает, если имя программы, назначение и строка вместе длиннее 16 символов.
lirtosiast

@ThomasKwa 26, на самом деле, поскольку у меня есть калькулятор цвета: P Технически это работает, если вы считаете перезаписывающую часть ввода «работающей».
МИ Райт

Первый действительно работает, если вы добавляете ClrHome: Input N, потому что текущий голос за мета для смешивания методов ввода / вывода - +7
lirtosiast

5

дк, 19

?pr256r^255/32*62+P

Ввод из STDIN. dcстроки являются определениями макросов и содержатся в [ ]. Строка пробелов генерируется путем вычисления числа, которое при выражении в виде 256-байтового потока дает нам нужную строку. Расчет есть ((n ^ 256) / 255) * 32). Это дает nпробелы (символ 32 ASCII), но нам нужно n-1следовать ^, поэтому мы просто добавляем 62 к последнему основному 256 разряду.

Выход

$ dc -e '?pr256r^255/32*62+P' <<< "2 [Lorem ipsum, dollar sit amet.]"
Lorem ipsum, dollar sit amet.
 ^$

4

C 59 57 47 байтов

f(a,c){for(puts(a);--c;putchar(32));puts("^");}

Довольно просто. Безголовая версия:

f(char* a,int c){
    puts(a);        //Print the string first

    for(;--c;)      //Until number-1 is not 0
        putchar(32);//Print a space
    puts("^");      //Print a caret
}

Проверьте это здесь.
Спасибо @anatolyg за сохранение 10 байтов!


Это более красиво двигаться puts(a)и putchar(32)в круглых скобках forцикла - есть ровно два пустых места есть! Кроме того, я не думаю, что вам нужно объявлять тип aи c- просто используйте intдля них неявный - будет работать, если вы этого не сделаете #include <stdio.h>.
Анатолий

@anatolyg, спасибо! Я не думал, что пропуск типов будет работать, но, к моему удивлению, это сработало.
Spikatrix

4

C # 55

Функция, концепция похожа на мой ответ C, но на этот раз возврат короче, чем вывод.

string f(string a,int b){return a+'\n'+"^".PadLeft(b);}

4

SAS, 35 байт

%macro a(n,s);put &s/@&n."^";%mend;

Это SAS-эквивалент голой функции; добавить шаг данных для его вызова (эквивалент функции C для вызова) будет немного больше (еще 9 байтов - Ty Alex), но я думаю, что для этого нет необходимости. Как это будет называться:

data;
%a(3,"My String");
run;

Существует реализация только для макросов, но она намного длиннее, даже если вы разрешите ей выдавать предупреждение о недопустимых параметрах при n = 1.

Если бы мы могли использовать предопределенные параметры, SAS был бы довольно коротким по сравнению с этим, что является редкостью для языка, который определенно не предназначен быть коротким.


Если набор данных разрешено использовать в качестве источника входных данных, как вы бы это «делали» в SAS (или с помощью инструкций% let), но, вероятно, это не разрешено, это еще короче ( 27 байтов , что на самом деле может быть 25 если вы гарантировали, что набор данных был создан непосредственно перед запуском этого [как вы могли бы просто использовать set;]):

(существующий набор данных)

data b;
  n=3;
  s="My String";
run;

(актуальный код)

data;set b;put s/@n"^";run;

Приятно видеть, что постоянный эксперт SAS SO здесь на PPCG. :)
Алекс А.

Я вполне уверен, что некоторые из старых таймеров, которые знают, что сценарии DM могли бы получить лучший результат ... И мои навыки cmdmac отстой.
Джо

Я всегда забываю, что DM даже существует, и я даже не знаю, что такое cmdmac! Кстати, когда вы подсчитываете байты для всего шага данных, вам не нужно data a;, вы можете просто сделать, data;что сэкономит 2 байта. Но, как вы сказали, это все равно не нужно для этого.
Алекс А.

Да, мои врожденные рефлексы SAS не позволяют мне использовать это интуитивно, я думаю :). Благодарю.
Джо

Говоря о старых таймерах, я думаю, вы могли бы сэкономить пару байтов, игнорируя всю интуицию SAS и используя макрос старого стиля. Я не могу вспомнить, могут ли они принимать параметры, хотя.
Алекс А.

3

Матлаб / Октава, 41

@(n,s)sprintf('%s\n%s^',s,ones(1,n-1)+31)

Это анонимная функция, которая возвращает строку. Это создает предупреждение, которое может быть подавлено предыдущим вызовом warning off.


Вы имеете в виду предупреждение редактора, или оно на самом деле печатает предупреждение для вас? Кроме того, я побил вас на 16 символов ;-) Но мой действительно печатает ans =бит, так что после исправления разница только в 10 символов.
Oebele

@Oebele выводит предупреждение, но возвращаемая строка не изменяется.
FryAmTheEggman

3

К, 21 байт

{y,"\n",1_|"^",x#" "}

Пример:

ryan@DevPC-LX:~/golf/caret$ rlwrap k
K Console - Enter \ for help

  `0:{y,"\n",1_|"^",x#" "}[2;"Lorem ipsum, dollar sit amet."]
Lorem ipsum, dollar sit amet.
 ^  

Пояснение ( xэто число, yэто строка):

{                   }   enclosing function
               x#" "    repeat the space `x` times
           "^",         prepend the caret
          |             reverse the string to put the caret at the end
        1_              drop the extra space
   "\n",                prepend a newline
 y,                     prepend the text

3

Р, 49 48 46

Как безымянная функция, которая выводит на STDOUT. Спасибо @Flounderer за улучшение.

теперь использует strwrap, чтобы идентифицировать каретку для n-1. cat использует разделитель \ n, а не пустую строку.

function(n,s)cat(s,strwrap('^',,n-1),sep='\n')

Тестовый забег

> f=function(n,s)cat(s,strwrap('^',,n-1),sep='\n')
> f(29,'The caret should point here v hopefully')
The caret should point here v hopefully
                            ^
>

функция (n, x) cat (x, "\ n", rep ("", n-1), "^", sep = "") - 48 символов
Flounderer

@Flounderer Спасибо за это ... моя оригинальная идея была похожа на это, но я не делал это так хорошо
MickyT

Если мне разрешено два начальных пробела, это работает: function(n,x)cat(" ",x,"\n",rep("",n),"^")и сохраняет несколько символов
Flounderer

@ Я подозреваю, что нет. У strwrap также есть некоторые возможности, но это, вероятно, закончится дольше.
MickyT

1
Это мило! Я никогда не видел strwrapфункцию раньше. Есть ли простой способ сказать, что он делает? Я не могу понять это из документации.
камбала

3

Python3, 38 36 байт

def f(s,i):return s+'\n'+' '*~-i+'^'

# OR 

def f(s,i):print(s+'\n'+' '*~-i+'^')

Проверьте это здесь.
Спасибо @Dennis за сохранение 2 байтов!


(i-1)->~-i
Деннис

Я слаб с битовыми операциями и математикой .... В любом случае, спасибо! :-D
Spikatrix

2

Юлия, 27 байт

(n,s)->s*"\n"*" "^(n-1)*"^"

Это создает безымянную функцию, которая принимает целое число и строку в качестве входных данных и возвращает строку. Чтобы назвать его, дайте ему имя, например f=(n,s)->....

Все, что здесь происходит, - это добавление новой строки, n-1пробелов и каретки. Конкатенация строк выполняется с использованием *и повторения строк с ^.

Ungolfed:

function f(n, s)
    s * "\n" * " "^(n-1) * "^"
end

Пример:

julia> println(f(2, "Lorem ipsum, dollar sit amet."))
Lorem ipsum, dollar sit amet.
 ^

2

PHP (CLI) - 42

<?=sprintf("%s\n%$argv[1]s",$argv[2],'^');

Вызовите это из командной строки:

php pointer.php 2 "Lorem ipsum, dollar sit amet."

Я заметил только сейчас. Но ваш ответ в точности как мой второй вариант. Я предлагаю это вам <?printf("$S\n%{$P}s",'^');. Заменить \nс реальным символом новой строки. Всего 5 байтов. Это работает только на PBP4.1 и ниже.
Исмаэль Мигель

Вау, так много ошибок в этом комментарии ... Я имел в виду, что он имеет длину 26 байт и работает только на PHP4.1. И это твое!
Исмаэль Мигель

2

Матлаб, 25

Этот очень нахальный. Видимо отображает распечатки непечатных символов в виде пробелов. Следующий код определяет функцию с именем ans, которая соответствует спецификациям.

@(N,S)[S 10 ones(N-1) 94]

так вызывая эту функцию так:

ans(2, 'Lorem ipsum, dollar sit amet.')

дает вывод:

ans =

Lorem ipsum, dollar sit amet.
 ^

Мне всегда не нравилась ans =роль в ответах Matlab. Если это проблема, мне нужно добавить 6 байтов ... но я всегда видел это в ответах Matlab. Обратите внимание, что выполнение этого кода перезаписывает переменную ans, поэтому вам нужно переопределить функцию, если вы хотите использовать ее во второй раз!


Очень хорошо! Я не знал, что строка в векторе работает так. Насколько я понимаю, поскольку это функция, строка возвращает ей значимое значение, и среда repl среды MATLAB просто распечатывает ее. т.е. если вы делаете, x=ans(2, 'asdf');вы не получите ответ = вещь.
FryAmTheEggman

2

Мой первый выстрел в Codegolf

Ява, 133 65

String g(int i,String s){for(s+="\n";--i>0;)s+=" ";return s+"^";}

Я уверен, что это может быть уменьшено еще больше.

Старый код

public void go(int i,String s){System.out.println(s);IntStream.range(1,i).forEach(j->System.out.print(" "));System.out.println("^");}

Вы можете хранить где- System.outнибудь?
Исмаэль Мигель

2
Нет необходимости public. И изменить IntStream.range(1,i).forEach(j->System.out.print(" "));наfor(;--i>0;)System.out.print(" ");
Spikatrix

@CoolGuy ага! иногда просто лучше
pallavt

Можете ли вы переместить s+="\n"внутрь for()инициализации, чтобы использовать точку с запятой там?
lirtosiast

@ThomasKwa на 1 байт меньше
pallavt

2

Свифт, 41

Вызывает разочарование , что Swift не имеет оператора *на Arrayили String.

{$1+reduce(0..<$0,"\n",{$0.0+" "})+"^"}

Для Swift 2.0:{$1+(0..<$0).reduce("\n"){$0.0+" "}+"^"}
Каметриксом

1

СпецБАС - 34

1 INPUT n,s$: PRINT s$'TAB n-1;"^"

Апостроф PRINTзаставляет новую строку, тогда просто нужно переместить курсор в правильное положение.



1

JavaScript - 52 байта

Вот мой, это довольно просто.

function f(n,s){return s+"\n"+Array(n).join(" ")+"^"}

Использование:

$ console.log(f(7, "Any string at all"))

Any string at all
      ^

Это указывает на седьмой символ.


Приятно сохранить Scimonster O_O
Флорри

1
Вы можете написать это как alert((P=prompt)()+"\n"+Array(P()+1).join(" ")+"^"). И вы экономите 2 байта. Кроме того, вы можете сделать это в stasksnippet, чтобы продемонстрировать работающий код. Ожидается, что сначала будет строка, а затем позиция
Исмаэль Мигель

1

Perl 5, 31

sub{"$_[0]
"." "x($_[1]-1)."^"}

Вы можете сохранить 2-3 символа. Удалите последний символ новой строки, так как он не требуется, затем измените первый символ новой строки на буквальный. (Perl в порядке с многострочными строками)
г-н Лама

@ Mr.Llama спасибо, это хорошо.
Хоббс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.