Преобразование имен заголовков C в имена заголовков C ++


27

В стандартной библиотеке C имена заголовков заканчиваются .hсуффиксом:

stdio.h

В C ++ эти имена заголовков доступны в альтернативной форме с cпрефиксом:

cstdio

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

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

Вот ваше базовое решение C. Он имеет 70 символов и выдает предупреждение о strlen:

void f(char*h){int i=strlen(h);h[--i]=0;while(--i)h[i]=h[i-1];*h='c';}

Самое короткое решение (измеряется количеством символов) выигрывает.

Обновление: если выбранный вами язык не поддерживает функции, также допустимы целые программы.

Обновление: Как предлагает FUZxxl, вот полный список заголовочных файлов в стандартной библиотеке C:

assert.h
ctype.h
errno.h
float.h
limits.h
locale.h
math.h
setjmp.h
signal.h
stdarg.h
stddef.h
stdio.h
stdlib.h
string.h
time.h

В частности, нет заголовков с несколькими точками в них.

Ответы:


37

80386 машинный код, 13 байт

Hexdump кода:

b0 63 86 01 41 3c 2e 75 f9 c6 01 00 c3

Исходный код (может быть скомпилирован Visual Studio):

__declspec(naked) void __fastcall conv(char s[])
{
    _asm {
        mov al, 'c';            // b0 63
    myloop:
        xchg al, [ecx];         // 86 01
        inc ecx;                // 41
        cmp al, '.';            // 3c 2e
        jne myloop;             // 75 f9
        mov byte ptr [ecx], 0;  // c6 01 00
        ret;                    // c3
    }
}

Он преобразует строку на месте. Код настолько прост, что ему не нужно сохранять и восстанавливать регистры (используя только alи ecx, что fastcallсоглашение позволяет использовать).



Определенно одно из лучших решений! Но исходный код на самом деле не 13 байт, а только скомпилированная форма (я думаю, что немногие из нас захотят писать в шестнадцатеричном редакторе).
Пер Лундберг,

3
Дай ему его победу. Байт = символ - вполне разумная интерпретация здесь.
Джошуа

7
@PerLundberg Я рассматриваю исходный код в этом случае как расширенное / прокомментированное объяснение «как это работает», которое многие люди включают в свои ультракомпактные языки. Для такой маленькой программы она вполне могла быть написана от руки. :)
пушистый

@ Флаффи Честная точка зрения. И да, число людей, которые могли бы написать бинарный код наизусть, безусловно,> 0, хотя я и не знаю никого, кто придурок сам. ;)
Пер Лундберг


14

CJam, 6 байтов

'clW(<

Это полная программа, которая читает строку через STDIN

Пояснение :

'c               "Put character c on stack";
  l              "Read a line from STDIN";
   W             "W is a predefined variable with value -1";
    (            "Decrease the value by 1";
     <           "Remove last 2 characters from the string on stack, the input argument";

Попробуйте это онлайн здесь


Не -2так хорошо, как W(?
Esolanging Fruit


11

брейкфук - 25 23 байта

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

Если выбранный вами язык не поддерживает функции, также допустимы целые программы.

Это целая программа, которая принимает данные от STDIN.

,[>,]      get all bytes of input
<-----.    subtract 5 from last byte (always "h"; "h" minus 5 = "c") and print result
<,         set second last byte to 0 by abusing comma
<[<]>      go to first byte
[.>]       print byte and move right until hitting 0

Не отступит ли это от левого края ленты на [<]
feersum

@feersum Если ваш переводчик позволяет вам сойти с левого края, да. Каждый, кого я когда-либо использовал, зацикливает ленту.
подземная

2
@feersum Если вы хотите попробовать это, но ваш переводчик позволяет вам отвалиться, вы можете исправить это с помощью кнопки >в начале.
подземный

10

Haskell - 23 персонажа

('c':).takeWhile(/='.')

Haskell - 16 символов, как предложено Ними

('c':).init.init

2
Отбрасывание последних 2 символов с помощью init.initвместо взятия всех до первого .экономит несколько байтов.
Nimi

@nimi Это потрясающее предложение!
fredoverflow

10

С, 38

См на идеоне

f(s,o){snprintf(o,strlen(s),"c%s",s);}

sявляется указателем на входную строку и oявляется местом, куда вывод должен быть записан.

Я нашел способ злоупотреблять snprintf. Выходная строка обычно оказывается на один символ короче входной, и максимальная длина записываемой строки на snprintf1 меньше nаргумента, поэтому она обрезает .h. Примечание: этот метод не будет работать с реализацией Microsoft, потому что он делает неправильные вещи и не может завершить строку нулем.


8

Пакетный файл Windows 11

@echo c%~n1

Первый переданный параметр - это% 1. Модификатор ~ n возвращает только имя файла без расширения.

Если также допустимо выводить расширенную команду на экран, то начальный @ можно удалить.


8

Архитектура узла TIS Тип T21 - 85 байт

Этот ответ просто для удовольствия; язык появился после того, как этот вызов был написан, и поэтому я не могу победить с ним. (Не то чтобы я собирался.)

Хорошо, я немного повеселился с этим. Мне, наверное, стоит просто назвать язык «TIS-100», но зачем ломать символ? : D

TIS-100 - игра о программировании компьютера с совершенно уникальной и причудливой архитектурой. Я написал специальную головоломку для этой задачи, которая позволяет мне принимать входные данные и сравнивать их с известной правильной «строкой». К сожалению, нет способа обрабатывать строки или символы, поэтому эта программа просто использует значение ASCII каждого символа для ввода и вывода.

Если вы хотите увидеть его в действии, вы можете использовать этот эмулятор или просто посмотреть, как я запускаю его в настоящей игре здесь . Обратите внимание, что в видео последняя строка первого узла D:MOV UP NIL. Закончив видео, я понял, что могу сыграть в гольф D:ADD UP. Функционально нет никакой разницы, потому что значение ACC в любом случае немедленно перезаписывается.

Это строка, которую я использовал для подсчета байтов:

MOV 99 ANY
MOV -46 ACC
ADD UP
JEZ D
ADD ACC ANY
JRO -5
D:ADD UP
MOV UP ANY
MOV UP ANY

Это текст каждого непустого узла, разделенного символами новой строки (фактически добавляя 1 байт для каждого узла, используемого после первого, отражая наше правило о коде в нескольких файлах).


7

Dyalog APL (8 символов)

'c',¯2↓⊢

Это решение точно такое же, как и решение J, которое я представил, но использует на один символ меньше, потому что оно на один символ меньше }..


7

J (9 знаков)

'c',_2}.]
  • |yэто величина из y(также называемой абсолютной величины)
  • x }. yбросает |xпредметы из y; предметы сбрасываются с фронта, если xположительный, с конца, если xотрицательный.
  • x , yдобавляет xи y.
  • 'c' , _2 }. yвыполняет преобразование, которое вы хотите; в молчаливом обозначении это может быть выражено как 'c' , _2 }. ].

7

Страус 0.6.0 , 8 символов

););"c\+

)является оператором "правильных вариантов". Применительно к строке она превращается, например, `foo`в `fo` `o`. ;используется для удаления лишнего символа, и это делается снова.

Затем "cтолкается. Это просто сокращение для `c`.

\+ Меняет местами два верхних элемента стека и объединяет их.


Этот язык был создан вами?
Исмаэль Мигель

@IsmaelMiguel Да. (См. Основной
репозиторий

Я хоть и так. Я уже проверил это, поэтому думаю об этом. Там нет ссылки на этот язык нигде. Только здесь. Итак, я предположил, что это было сделано вами. Для 14-летнего парня вы очень далеко зашли в программировании. +1000 за это!
Исмаэль Мигель

@IsmaelMiguel. Ой, простите, я должен был сказать вам, что я - KeyboardFire на Github. Благодарность!
Ручка

Вам не нужно. Это почти подразумевается. Я ismael-miguel (очень оригинально, проверьте github.com/ismael-miguel ). У меня там нет ничего интересного и полезного, но вы можете это проверить. Но мне интересен твой язык. Единственная завершенная вещь - это класс UIntArray для php ( github.com/ismael-miguel/php-uintarray, если вы заинтересованы).
Исмаэль Мигель

7

Пит ( 9x11 = 99 8X11 = 88)

v2

еще одна попытка (2x37 = 74)

введите описание изображения здесь

Трудно сделать его намного меньше, поскольку ему нужно сгенерировать 99 ('c') и 46 ('.'), И это занимает место в пите.


1
Пит никогда не измеряется в символах, только в коде, так что вам не нужно упоминать бит 0 символов :) Также много белого
Sp3000

пытаюсь сжать, но это немного сложно. Возникли проблемы с его завершением, если я удалю еще одну строку или столбец.
captncraig

Это немного измены, но мне это нравится. Это похоже на использование в /dev/nullкачестве исходного кода.
Исмаэль Мигель

2
Согласно META ( meta.codegolf.stackexchange.com/questions/4782/… ), ваша программа не обязана завершать. Пока это делает свою задачу, ваша программа может работать вечно. Прочитайте первый ответ на вопрос.
Исмаэль Мигель

6

F # - 39 37 31

31 - Потому что типизация в F # рулит!

fun s->("c"+s).Replace(".h","")

37

fun(s:string)->"c"+s.Replace(".h","")

39

fun(s:string)->"c"+s.Remove(s.Length-2)

Не работает для заголовка с именем foo.hoo.h.
FUZxxl

3
@FUZxxl В стандартной библиотеке C таких заголовков нет.
fredoverflow

@FredOverflow Возможно, вы захотите указать набор имен, с которыми должно работать преобразование. Прямо сейчас ваш вопрос сформулирован таким образом, что люди могут предположить, что этот вид ввода должен работать правильно.
FUZxxl

@FUZxxl Я обновил вопрос соответственно.
fredoverflow



4

GNU sed -r, 14

У sed на самом деле нет никакого понятия о функциях, так что вместо этого вот полная программа sed:

s/(.*)../c\1/

Выход

$ sed -r 's/(.*)../c\1/' <<< stdio.h
cstdio
$ 

-rБыла включена в счет , как один дополнительный характер.


Это решение недействительно: скорее всего, оно должно быть s/\(.*\)\.h/c\1/.
FUZxxl

@FUZxxl - я предполагаю, -rчто передается в sed. Как и в обычном код-гольфе, мне нужно считать это дополнительным баллом.
Цифровая травма

@DigitalTraume Обратите внимание, что -rэто не стандартная опция и недоступная вне GNU sed. Вы можете изменить название языка на GNU sed, чтобы отразить это.
FUZxxl

@FUZxxl Да. Выполнено.
Цифровая травма

2
\.hможет быть сокращено до..
Стивен Тащук

3

Прелюдия , 31 персонаж

Поскольку полные представления программы, по-видимому, приемлемы, вот программа, которая читает заголовок в стиле C из STDIN и печатает заголовок в стиле C ++ в STDOUT:

99+9+(?)###(#
9(1-)       ^)(!)

Это требует стандартного интерпретатора, который печатает вывод в виде кодов символов. Если вы используете интерпретатор Python, вам нужно установить NUMERIC_OUTPUT = False.

Также требуется, чтобы на STDIN не было завершающей новой строки.

объяснение

В Prelude все строки выполняются параллельно, по одному столбцу за раз. Каждая строка имеет свой собственный стек, инициализированный бесконечным количеством 0s.

99+9+
9(1-)

Это самое короткое, что я мог придумать, чтобы получить 99верхний стек (код символа c). Сначала я складываю 18верхний стек и помещаю 9в нижний стек. Затем нижняя часть ведет обратный отсчет 0в цикле, а верхний стек добавляет больше 9s. Это добавляет к 99верхнему стеку, и нижний стек 0снова остается с s. Обратите внимание, что все +9+является частью цикла, так что фактически на одну итерацию приходится две операции сложения, но это не проблема, благодаря бесконечному количеству 0s снизу.

Теперь (?)читает STDIN, по одному символу за раз и помещает в верхний стек. Цикл заканчивается в конце ввода, когда ?толкает ноль. ###избавляется от этого нуля, hи .. Теперь следующий цикл извлекает числа из верхнего стека и копирует их в нижний стек. Это существенно меняет стек. Обратите внимание, что открывающая и закрывающая скобки находятся на разных строках - это не проблема, потому что вертикальное положение не )имеет значения в Prelude, но это экономит мне байт в первой строке.

Наконец, (!)печатает все символы, пока стек не станет пустым.


3

Pyth, 7 символов

L+\cPPb

Объяснение:

L         def y(b):return
 +\c                      "c" +
    PPb                         b[:-1][:-1]

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

L+\cPPb
y"stdio.h

на онлайн компилятор / исполнитель Pyth


Если полные программы были разрешены:

Pyth, 6 символов

+\cPPQ

Я никогда не видел Пита. Будете ли вы так добры и объясните код? :)
fredoverflow


Я считаю, что вы можете использовать PPbвместо<b_2
FryAmTheEggman

@FryAmTheEggman Спасибо.
Исаак

Кажется, что полные программы разрешены, так что вы можете перейти к 6.
FryAmTheEggman

3

C ++ 14, 41 символов

[](auto&s){s="c"+s.substr(0,s.size()-2);}

Вдохновлен этим другим ответом. Я сделал это отдельным ответом, потому что здесь я использую функцию, новую в c ++ 14, обобщенную лямбду .

Смотрите это в действии здесь .


2

T-SQL - 58 символов

CREATE PROC Q(@ VARCHAR(MAX))AS
SELECT'c'+LEFT(@,LEN(@)-2)

Запустите как EXEC Q (ваша строка здесь)


2

Perl - 20 символов

sub{c.pop=~s/..$//r}

Обратите внимание, как cэто голое слово и как таковое требует отсутствия use strict. Это должно быть использовано как выражение, а не как утверждение.


2

Марбелоус, 24

@063
-Z//
3W<C+Z
]]!!
@0

Принимает ввод через STDIN, выводит в STDOUT.

Это работает путем проверки каждого байта с помощью .( 0x46). Так как 0x46не может поместиться в одну цифру base-36, мы вычитаем 35 ( Z) перед сравнением и добавляем обратно перед выводом.

Каждый мрамор дублируется 3W(трехсторонний дубликатор, но левая сторона сбрасывается со стороны доски). Мрамор, отправленный вниз, получает следующий байт от STDIN. Мрамор справа проверяется ., затем выводится или отправляется !!, что завершает программу.

Программа начинается с прохода c( 0x63) через, который будет выводиться в STDOUT.

Попробуйте это онлайн здесь. Библиотеки должны быть включены, цилиндрические доски должны быть отключены.


2

С, 64

Слегка короче, чем c ссылка:

f(char*h){char*d=strstr(h,".");memmove(h+1,h,d++-h);*d=0;*h=99;}

Вероятно, больше игры в гольф будет сделано с этим.


C, 48 (libc hack)

f(char*h){strcpy(h+1,h);*strstr(h,".")=0;*h=99;}

На strcpyman-странице прямо сказано: «Строки не должны перекрываться». Однако я обнаружил, что используемая мной библиотека libc, похоже, кодируется безопасно для правильной обработки. Это библиотека GNU C (Ubuntu EGLIBC 2.19-0ubuntu6.4) в Ubuntu 14.04.


Допускается ли пропуск типа возврата функции в C89?
fredoverflow

1
@FredOverflow. Да - GCC компилирует это просто отлично -std=c89. codegolf.stackexchange.com/a/2204/11259
Цифровая травма

@FredOverflow Да. Тип возвращаемого значения по умолчанию int.
FUZxxl

Страница man просто повторяет Стандарт - компиляция этого с VC ++ (VS2012) дает "cstdii" для "stdio.h". Не проверял ICC / Sun / clang, но ваша 64-символьная версия говорит "почему?" - он настолько короток, насколько это возможно (юридически) быть в C.
французски

2

JavaScript (ES6) 20

Не могу поверить, что ES6 все еще отсутствует

s=>'c'+s.slice(0,-2)


2

мк, 34 символа

mk (1) - это замена Plan 9 для make. Просто для удовольствия, этот mkfile преобразует имена заголовков C в имена заголовков C ++:

c%:Q:
    :

%.h:Q: c%
    echo $prereq

Существует одна вкладка до :и echo. Используйте как это:

% mk stdio.h
cstdio



1

Р, 33

function(x)sub("(.+)..","c\\1",x)

Эта функция использует регулярные выражения.

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

> (function(x)sub("(.+)..","c\\1",x))("stdio.h")
[1] "cstdio"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.