Konwertuj nazwy nagłówków C na nazwy nagłówków C ++


27

W standardowej bibliotece C nazwy nagłówków kończą się .hprzyrostkiem:

stdio.h

W C ++ te nazwy nagłówków są dostępne w alternatywnej formie z cprefiksem:

cstdio

Napisz funkcję, która konwertuje pierwszą formę na drugą. Możesz dokonać konwersji w miejscu lub pozostawić oryginalny ciąg nienaruszony i zwrócić nowy ciąg. Cokolwiek wydaje się naturalne w wybranym języku.

Kod musi zostać skompilowany / zinterpretowany bez błędów. Ostrzeżenia kompilatora są dopuszczalne.

Oto twoje podstawowe rozwiązanie C. Ma 70 znaków i generuje ostrzeżenie o strlen:

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

Najkrótsze rozwiązanie (mierzone liczbą znaków) wygrywa.

Aktualizacja: jeśli wybrany język nie obsługuje funkcji, dopuszczalne są również całe programy.

Aktualizacja: Jak sugeruje FUZxxl, oto pełna lista plików nagłówkowych w standardowej bibliotece 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

W szczególności nie ma nazw nagłówków z wieloma kropkami.

Odpowiedzi:


37

Kod maszynowy 80386, 13 bajtów

Hexdump kodu:

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

Kod źródłowy (może zostać skompilowany przez 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
    }
}

Konwertuje ciąg w miejscu. Kod jest tak prosty, że nie trzeba zapisywać i przywracać rejestrów (tylko przy użyciu ali ecx, zgodnie z fastcallkonwencją, pozwala to na clobber).


Fajnie, to zabiera mnie z powrotem :)
fredoverflow

Zdecydowanie jedno z fajniejszych rozwiązań! Ale kod źródłowy nie jest tak naprawdę 13 bajtami, tylko jego skompilowana forma (myślę, że niewielu z nas chciałoby pisać w edytorze szesnastkowym).
Per Lundberg,

3
Daj mu swoją wygraną. Bajt = znak jest tutaj całkowicie rozsądną interpretacją.
Joshua

7
@PerLundberg Widzę w tym przypadku kod źródłowy jako „jak to działa” rozszerzone / skomentowane wyjaśnienie, które wiele osób zawiera w swoich ultra-kompaktowych językach. W przypadku tak małego programu równie dobrze mógłby być napisany ręcznie. :)
puszysty

@fluffy Fair point. I tak, liczba osób, które mogłyby napisać kod binarny na pamięć, to z pewnością> 0, chociaż sam nie znam nikogo, kto by się tak nazywał. ;)
Per Lundberg


14

CJam, 6 bajtów

'clW(<

Jest to pełny program, który odczytuje ciąg znaków przez STDIN

Objaśnienie :

'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";

Wypróbuj online tutaj


Czy nie -2jest tak dobry jak W(?
Esolanging Fruit


11

brainfuck - 25 23 bajtów

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

Jeśli wybrany język nie obsługuje funkcji, dopuszczalne są również całe programy.

Jest to cały program, który pobiera dane wejściowe ze 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

Czy to nie
zejdzie

@feersum Jeśli twój tłumacz pozwala ci zejść z lewej krawędzi, tak. Każdy, którego kiedykolwiek użyłem, zapętla taśmę.
metro

2
@feersum Jeśli chcesz spróbować, ale Twój tłumacz pozwala ci spaść, możesz to naprawić >na początku.
undergroundmonorail

10

Haskell - 23 znaków

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

Haskell - 16 znaków, jak sugerują nimi

('c':).init.init

2
Usunięcie dwóch ostatnich znaków init.initzamiast zamiast wzięcia wszystkich do pierwszego .pozwala zaoszczędzić kilka bajtów.
nimi

@nimi To niesamowita sugestia!
fredoverflow

10

C, 38

Zobacz na Ideone

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

sjest wskaźnikiem do łańcucha wejściowego i ojest miejscem, w którym należy zapisać dane wyjściowe.

Znalazłem sposób na znęcanie się snprintf. Ciąg wyjściowy dogodnie jest o jeden znak krótszy niż wejście, a maksymalna długość napisanego ciągu snprintfjest o 1 mniejsza niż nargument, więc odcina .h. Uwaga: ta technika nie będzie działać z implementacją Microsoftu, ponieważ robi coś złego i nie przerywa łańcucha zerowo.


8

Plik wsadowy Windows 11

@echo c%~n1

Pierwszy przekazany parametr to% 1. Modyfikator ~ n zwraca tylko nazwę pliku bez rozszerzenia.

Jeśli akceptowalne jest także echo rozwiniętego polecenia na ekranie, można usunąć początkowe @.


8

Architektura węzła TIS Typ T21 - 85 bajtów

Ta odpowiedź jest dla zabawy; język powstał po napisaniu tego wyzwania i dlatego nie mogę z nim wygrać. (Nie to, że zamierzałem.)

Okej, bawiłem się trochę z tym. Prawdopodobnie powinienem po prostu nazwać język „TIS-100”, ale po co łamać charakter? :RE

TIS-100 to gra o programowaniu komputera o całkowicie unikalnej i dziwnej architekturze. Napisałem niestandardową łamigłówkę do tego wyzwania, która pozwala mi pobierać dane wejściowe i sprawdzać dane wyjściowe względem znanego poprawnego „ciągu”. Niestety nie ma sposobu na obsługę ciągów lub znaków, więc ten program po prostu używa wartości ASCII każdego znaku do wprowadzania i wyprowadzania.

Jeśli chcesz, aby zobaczyć go w akcji, można użyć tego emulatora , albo po prostu obejrzeć mi uruchomić go w rzeczywistej grze tutaj . Zauważ, że w filmie ostatnia linia pierwszego węzła to D:MOV UP NIL. Po skończeniu filmu zdałem sobie sprawę, że mogę to pograć w golfa D:ADD UP. Funkcjonalnie nie ma różnicy, ponieważ i tak wartość ACC jest natychmiast zastępowana.

Oto ciąg, którego użyłem do mojej liczby bajtów:

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

Taki jest tekst każdego niepustego węzła, oddzielony znakami nowej linii (skutecznie dodając 1 bajt dla każdego węzła używanego poza pierwszym, odzwierciedlając naszą regułę dotyczącą kodu w wielu plikach).


7

Dyalog APL (8 znaków)

'c',¯2↓⊢

To rozwiązanie jest dokładnie takie samo jak rozwiązanie J, które przesłałem, ale używa o jeden znak mniej, ponieważ jest o jeden znak mniej niż }..


7

J (9 znaków)

'c',_2}.]
  • |yjest wielkością z y(zwany również wartość bezwzględna)
  • x }. yupuszcza |xprzedmioty z y; przedmioty są upuszczane z przodu, jeśli xjest dodatnie, od końca, jeśli xjest ujemne.
  • x , ydołącza xi y.
  • 'c' , _2 }. yczy transformacja, którą chcesz; w milczącej notacji można to wyrazić jako 'c' , _2 }. ].

7

Struś 0,6 , 8 znaków

););"c\+

)jest operatorem „właściwych Unons”. Po zastosowaniu do łańcucha zmienia się na przykład `foo`w `fo` `o`. ;służy do wyskakiwania dodatkowej postaci i dzieje się to ponownie.

Następnie "cjest popychany. To po prostu skrót `c`.

\+ zamienia dwa górne elementy stosu i łączy je.


Czy ten język został stworzony przez Ciebie?
Ismael Miguel

@IsmaelMiguel Tak. (Zobacz główne repozytorium Github .)
Klamka

Tak myślałem Już to sprawdziłem, dlatego o tym myślę. Nigdzie nie ma odniesienia do tego języka. Tylko tutaj. Więc założyłem, że to twoja sprawa. Jak na 14-letniego faceta, zaszedłeś naprawdę daleko w programowaniu. +1000 za to!
Ismael Miguel

@ IsmaelMiguel Ups, przepraszam, powinienem był powiedzieć, że jestem KeyboardFire w Github. Dzięki!
Klamka

Nie musisz. To prawie dorozumiane. Jestem ismael-miguel (bardzo oryginalny, sprawdź github.com/ismael-miguel ). Nie mam tam nic ciekawego i użytecznego, ale możesz to sprawdzić. Ale interesuje mnie twój język. Jedyną kompletną rzeczą jest klasa UIntArray dla php ( github.com/ismael-miguel/php-uintarray, jeśli jesteś zainteresowany).
Ismael Miguel

7

piet ( 9x11 = 99 8X11 = 88)

v2

kolejna próba (2x37 = 74)

wprowadź opis zdjęcia tutaj

Trudno go znacznie zmniejszyć, ponieważ musi wygenerować 99 („c”) i 46 („.”), A to zajmuje miejsce w piecie.


1
Piet nigdy nie jest mierzony w znakach, tylko w kodach, więc nie trzeba wspominać o 0
znakach

próba kompresji, ale jest to trochę trudne. Mam problem z zakończeniem działania, jeśli usunę kolejny wiersz lub kolumnę.
captncraig

To trochę oszustwo, ale mi się podoba. To jest jak użycie /dev/nullkodu źródłowego.
Ismael Miguel

2
Według META ( meta.codegolf.stackexchange.com/questions/4782/... ) twój program nie musi się kończyć. Tak długo, jak to robi, twój program może działać wiecznie. Przeczytaj pierwszą odpowiedź na pytanie.
Ismael Miguel

6

F # - 39 37 31

31 - Ponieważ typowanie w skałach 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)

Nie działa w przypadku nagłówka o nazwie foo.hoo.h.
FUZxxl,

3
@FUZxxl W bibliotece standardowej C nie ma takich nagłówków.
fredoverflow

@FredOverflow Możesz określić zestaw nazw, na których ma działać transformacja. W tej chwili twoje pytanie jest sformułowane w sposób, który może prowadzić do założenia, że ​​tego rodzaju dane wejściowe muszą działać poprawnie.
FUZxxl,

@FUZxxl Zaktualizowałem pytanie odpowiednio.
fredoverflow



4

GNU sed -r, 14

sed tak naprawdę nie ma pojęcia o funkcjach, więc zamiast tego jest pełny program sed:

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

Wydajność

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

-rZostała ujęta w partyturze jako jednego dodatkowego charakteru.


To rozwiązanie jest nieprawidłowe: prawdopodobnie powinno być s/\(.*\)\.h/c\1/.
FUZxxl,

@FUZxxl - Zakładam, że -rzostał przekazany do sed. Jak zwykle w golfa kodowego muszę to liczyć jako dodatkowy punkt.
Cyfrowa trauma

@DigitalTraume Uwaga, która -rnie jest standardową opcją i nie jest dostępna poza GNU sed. Możesz chcieć zmienić nazwę języka na GNU sed, aby to odzwierciedlić.
FUZxxl,

@FUZxxl Tak. Gotowy.
Cyfrowa trauma

2
\.hmożna skrócić do..
Steven Taschuk

3

Preludium , 31 znaków

Ponieważ najwyraźniej dopuszczalne jest przesyłanie pełnego programu, oto program, który odczytuje nagłówek w stylu C ze STDIN i drukuje nagłówek w stylu C ++ do STDOUT:

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

Wymaga to zgodnego ze standardami interpretera, który drukuje dane wyjściowe jako kody znaków. Jeśli używasz interpretera Python , musisz ustawić NUMERIC_OUTPUT = False.

Wymaga to również, że nie ma końcowego nowego wiersza na STDIN.

Wyjaśnienie

W Preludium wszystkie wiersze są wykonywane równolegle, jedna kolumna na raz. Każda linia ma swój własny stos, zainicjowany na nieskończoną liczbę 0s.

99+9+
9(1-)

Jest to najkrótszy czas, jaki mogłem wymyślić, aby dostać się 99na najwyższy stos (kod znaków c). Najpierw sumuję 18na górnym stosie i wciskam 9na dolny stos. Dół następnie odlicza do 0pętli, podczas gdy górny stos dodaje więcej 9s. To sumuje się do 99górnego stosu, a dolny stos jest 0ponownie z s. Zauważ, że wszystko +9+jest częścią pętli, więc w rzeczywistości istnieją dwie operacje dodawania na iterację, ale to nie jest problem, dzięki nieskończonej podaży 0s pod nią.

Teraz (?)odczytuje STDIN, jedną postać na raz i przesuwa na najwyższy stos. Pętla kończy się na końcu wejścia, gdy ?popycha zero. ###pozbywa się tego zera, hi .. Teraz następna pętla wyskakuje liczby z górnego stosu podczas kopiowania ich do dolnego stosu. To zasadniczo odwraca stos. Zauważ, że nawiasy otwierające i zamykające są na różnych liniach - to nie jest problem, ponieważ pionowa pozycja nie )ma znaczenia w Preludium, ale oszczędza mi bajt w pierwszej linii.

Na koniec (!)drukuje wszystkie znaki, aż stos będzie pusty.


3

Pyth, 7 znaków

L+\cPPb

Wyjaśnienie:

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

Spróbuj tego:

L+\cPPb
y"stdio.h

w internetowym kompilatorze / executorze Pyth


Jeśli dozwolone są pełne programy:

Pyth, 6 znaków

+\cPPQ

Nigdy nie widziałem Pytha. Czy byłbyś tak miły i wyjaśniłby kod? :)
fredoverflow


Wierzę, że możesz użyć PPbzamiast<b_2
FryAmTheEggman

@FryAmTheEggman Thanks.
isaacg

Wygląda na to, że dozwolone są pełne programy, więc możesz dostać się do 6.
FryAmTheEggman

3

C ++ 14, 41 znaków

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

Zainspirowany tym innej odpowiedzi. Zrobiłem to osobną odpowiedź, ponieważ tutaj używam funkcji, która jest nowa w c ++ 14, ogólna lambda .

Zobacz to w akcji tutaj .


2

T-SQL - 58 znaków

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

Uruchom jako EXEC Q (tutaj Twój ciąg)


2

Perl - 20 znaków

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

Zwróć uwagę, jak cto jest słowo-słowo i jako takie wymaga jego braku use strict. To musi być użyte jako wyrażenie, a nie wyrażenie.


2

Marbelous, 24

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

Pobiera dane wejściowe przez STDIN, dane wyjściowe do STDOUT.

Działa to poprzez sprawdzenie każdego bajtu za pomocą .( 0x46). Ponieważ 0x46nie może zmieścić się w jednej cyfrze bazowej 36, odejmujemy 35 ( Z) przed porównaniem i dodajemy go z powrotem przed wypisaniem.

Każdy marmur jest powielany przez 3W(trójdrożny powielacz, ale lewa strona jest odrzucana z boku planszy). Marmur skierowany w dół pobiera następny bajt ze STDIN. Marmur po prawej stronie jest sprawdzany ., a następnie albo wysyłany, albo wysyłany do !!, co kończy program.

Program rozpoczyna się od przekazania c( 0x63), które zostanie wyprowadzone do STDOUT.

Wypróbuj online tutaj. Biblioteki muszą być włączone, płyty cylindryczne muszą być wyłączone.


2

C, 64

Nieco krótszy niż odniesienie c:

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

Prawdopodobnie więcej golfa można z tym zrobić.


C, 48 (hack libc)

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

Strona strcpyman wyraźnie stwierdza „Ciągi nie mogą się nakładać”. Odkryłem jednak, że libc, którego używam, wydaje się być bezpiecznie zakodowany, aby mimo wszystko poprawnie się z tym obchodzić. To jest biblioteka GNU C (Ubuntu EGLIBC 2.19-0ubuntu6.4) na Ubuntu 14.04.


Czy pominięcie typu zwracanego funkcji jest legalne w C89?
fredoverflow

1
@FredOverflow. Tak - gcc dobrze to kompiluje -std=c89. codegolf.stackexchange.com/a/2204/11259
Cyfrowa trauma

@FredOverflow Tak. Typ zwracany jest domyślnie int.
FUZxxl,

Strona podręcznika po prostu przypomina Standard - kompilacja tego z VC ++ (VS2012) daje „cstdii” dla „stdio.h”. Nie sprawdzałem ICC / Sun / clang, ale twoja 64-znakowa wersja mówi „dlaczego?” - jest tak krótki, jak to tylko możliwe (legalnie) w C.
frasnian

2

JavaScript (ES6) 20

Nie mogę uwierzyć, że ES6 wciąż brakowało

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


2

mk, 34 znaki

mk (1) zastępuje markę Plan 9. Dla zabawy ten plik mk konwertuje nazwy nagłówków C na nazwy nagłówków C ++:

c%:Q:
    :

%.h:Q: c%
    echo $prereq

Istnieje jedna karta przed :i echo. Użyj w ten sposób:

% mk stdio.h
cstdio



1

R, 33

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

Ta funkcja używa wyrażeń regularnych.

Przykładowe użycie:

> (function(x)sub("(.+)..","c\\1",x))("stdio.h")
[1] "cstdio"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.