Для PHP 5.5
в CentOS
я исправил это, установив пакет php55-mysqlnd
.
sudo yum -y install php55w-mysqlnd # For Webtatic
sudo yum -y install php55u-mysqlnd # For Remi
Для помощи в установке, напишите комментарий, поскольку он зависит от того, как PHP установлен на вашем система. Доступными репо являются webtatic
и remi
.
All linebreaks may be removed.
@s=unpack"C*",~"P\xdbLI\xc3a`[\@AB\xe0t\xc8df";
$_=<>;for$s(6,3,0){print map$s[hex$&]&1<<$_+$s?$_%2?"_":"|":" ",
0..2while/./g;print$/}
@s
stores the bits for each segment. The entries are in order from 0 to F (thanks to hex()
) and the bits map to segments in this order:
6 7 x
3 4 5
0 1 2
with 0
being the LSB. (Bit 6 is unused). The values are stored packed in the string bit-inverted so there are a lot more printable characters; the ~
operator flips the bits and unpack gives me numbers (perl's bitwise operators are much clumsier when it comes to strings).
With the data in hand I read the input and proceed to loop over it three times; the only difference between the three loops is the bitmask required. For each character of input three characters of output are printed. The character to be printed is
$s[ hex $& ] & (1 << ($_ + $s) )
? ($_ % 2 ? "_" : "|" )
: " "
where @s
is the lookup table, $s
is the shift in effect depending on the row, and $_
is whether we're printing the 1st, 2nd, or 3rd character in the row. If the right bit in the lookup table entry is false it prints a space; otherwise it prints a "|" on the sides or a "_" in the middle.
print(lambda l:(lambda s:'\n'.join([' '.join(x) for x in zip(*[l[c].split('\n')
for c in s])])))(dict(zip('0123456789abcdef', 'eJxdjrEBwDAIw3au0Ac9iUd0fJM2DTQD'
'g5ExJgkxTOMKYIzPDDUYORlNsZ3zppwuXsqt/pmmjVmZ\nH6M+9BTXZvU8Umg9fd03SOgvPw=='
.decode('base64').decode('zlib').split('\n/\n'))))(__import__('sys').argv[-1]
.lower())
Большая часть длины из-за того, что я был ленив и использовал встроенные функции zlib и base64 для таблицы поиска. Запустите его из командной строки следующим образом:
$ python golf.py fedcba9876543210
Haskell, 259 символов.
Haskell плох для гольфа или это я (мой первый гольф)?
import Char
i=iterate
d b=map(`mod`b).i(`div`b)
z _ 0=' '
z a 1=a
r=take 3
main=
getLine>>=
putStr.unlines.foldl1(zipWith(++)).
map(r.map r.i(drop 3).take 9.zipWith z(cycle"|_|").(0:).d 2.
(d 256(0xddfd91edcd9cd97990f5*2^384+0x2d6df865ecbd*(2^520+2^776))!!).ord)
(разделить основную часть на строки для удобства чтения)
Compiles with -Wall and can be understood; not very short (~400 chars). In a serious implementation, I'd pull the char->index out of the output part (and store the indices in a buffer rather than the chars). Global r is initialized to 0, which it wouldn't if it were a local in main.
#include <stdio.h>
typedef char const* R;
R _=" _ ",S=" ",I=" |",J=" _|",L="|_ ",U="|_|",N="| |",C="| ";
R s[][16]={
{_,S,_,_,S,_,_,_,_,_,_,S,_,S,_,_},
{N,I,J,J,U,L,L,I,U,U,U,L,C,J,L,L},
{U,I,L,J,I,J,U,I,U,J,N,U,L,U,L,C}};
int r,c,i;
int main(){
char b[999];
scanf("%s",b);
for(;r<3;++r)
for(c=0;;) {
i=b[c++]-'0';
if (i>16) i-=7;
if (i>15) i-=32;
if (i<0||i>15){putchar('\n');break;}
printf("%s",s[r][i]);
}
return 0;
}
Возможно, есть лучший способ сделать это, но вот мое решение:
using C=System.Console;class Z{static void Main(){new Z();}int L=0;Z(){
try{var s=C.ReadLine().ToUpper();C.Clear();foreach(var c in s){int n=(
int)c;var p=(n==48?"_ ;| |;|_|":n==49?"; |; |":n==50?"_; _|;|_":n==51
?"_; _|; _|":n==52?";|_|; |":n==53?"_;|_; _|":n==54?"_;|_;|_|":n==55?
"_; |; |":n==56?"_;|_|;|_|":n==57?"_;|_|; _|":n==65?"_;|_|;| |":n==66
?";|_;|_|":n==67?"_;|;|_":n==68?"; _|;|_|":n==69?"_;|_;|_":n==70?"_;|_;|"
:";;").Split(';');P(0);C.Write(" "+p[0]);P(1);C.Write(p[1]);P(2);C.Write
(p[2]);L+=4;}C.WriteLine();}catch{}}void P(int t){C.SetCursorPosition(L,t);}}
Мой не Короче говоря, это было забавно:
~ dlamblin$ ./7seg 31337aAbcdeF
_ _ _ _ _ _ _ _ _
_| | _| _| ||_||_||_ | _||_ |_
_| | _| _| || || ||_||_ |_||_ |
#include <stdio.h>
#define P(x) fputs(x,stdout)
#define Z "\33[3D\33[B"
#define a " " Z
#define s " _ " Z
#define d " |" Z
#define f " _|" Z
#define g "| " Z
#define h "| |" Z
#define j "|_ " Z
#define k "|_|" Z
int main(int argc, char** argv){
char m=0,n,*b[]={s h k,a d d,s f j,s f f,a k d,s j f,s j k,s d d,s k k,s k d,
"","","","","","","",
s k h,a j k,s g j,a f k,s j j,s j g};
P("\n\n\n\33[3A");
while (argc>1&&0!=(n=argv[1][m++])){
P(b[n>96?n-80:n-48]);P("\33[3A\33[3C");
}
P("\n\n\n");
}
Вы можете сохранить пару символов, удалив некоторые символы новой строки, но меня это не волнует.
Это 500 символов или 482, если вы уберете символы новой строки и argc> 1 &&
Требуется поддержка escape-кода VT100 и не будет выводить более 26 символов на терминале с 80 столбцами.
PS Я бы хотел хотели бы видеть больше людей, демонстрирующих свою продукцию.
Хехе, все придумали более лаконичный способ представления данных.
В любом случае, чтобы это было не будет пустой тратой времени (ввод из командной строки):
#include<cstdio>
#define P(x)putchar(x);
int main(int,char**v){int i,j,d[]={0,6947821,0,7209841,7734140,1180575,8257861,
3933037,1442811};char*p,c[]="|_|";for(++v;*v;++v){for(i=0;i<9;i+=3){for(p=*v;*p;
++p){for(j=0;j<3;++j)P(1<<((*p>96?*p-32:*p)-48)&d[i+j]?c[j]:32)P(32)}P(10)}P(10)
}}
И без запутывания:
#include <cstdio>
void out(const char* s)
{
int i, j;
const char* c = "|_|";
unsigned d[9] = {0, 6947821, 0, 7209841, 7734140, 1180575, 8257861, 3933037, 1442811};
for (i = 0; i < 9; i += 3) {
for (const char* p = s; *p; ++p) {
for (j = 0; j != 3; ++j)
putchar(1 << ((*p > 96 ? *p - 32 : *p) - '0') & d[j + i] ? c[j] : ' ');
putchar(' ');
}
putchar('\n');
}
}
int main(int, char** argv)
{
for (++argv;*argv;) {
out(*argv++);
putchar('\n');
}
}
Магические числа относятся к тому, какие символы имеют _ или | в определенной позиции. Например, если 0, 3, 5 и 'A' имеют | где-то число будет 1 << n ('0') | 1 << n ('3') | 1 << n ('5') | 1 << n ('A')
- где n (x)
означает x - '0'
. Это предполагает наличие как минимум 32-битных целых чисел, так как между '9'
и 'A'
в таблице ASCII есть небольшой промежуток.
Оба кода были недавно отредактированы:
Much shorter than earlier version, using some ideas from JRL. Could be made shorter by using command line arguments, but that goes against the spec.
class D{public static void main(String[]a){char[]q=new java.util.Scanner
(System.in).nextLine().toCharArray();int j=0,k;for(;j<9;j+=3){for(int c:
q){for(k=j;k<j+3;k++){System.out.print(("{H=mNgwI\177o_v3|7\027".charAt(
"0123456789abcdef".indexOf(c|32))&"\0\1\0\2\4\10\20 @".charAt(k))>0?
" _ |_||_|".charAt(k):32);}}System.out.println();}}}
My first code golf. 279 non-whitespace characters, 433 including spaces. I'm sure it could be shorter in Python.
Python
import sys
w = sys.stdout.write
i = raw_input()
d = [111,9,94,91,57,115,119,73,127,123,125,55,102,31,118,116]
p = [' _ ','|','_','|','|','_','|']
j = 0
for r in range(3):
for c in i.lower():
for n in range(3 if r else 1):
s = p[j+n]
if (1<<6-j-n) & d[ord(c)-(ord('0') if c.isdigit() else ord('a')+6)]:
w(s)
else:
w(' '*len(s))
j += n+1
w('\n')
Я не слишком много смотрел на другие решения, но уверен, что есть еще много возможностей для улучшения.
n=int(raw_input(),16)
O=[""]*3
while n:O=["".join(" |_"[(m>>n%16*3+i&1)*(i%2+1)]for i in[2,1,0])+o
for o,m in zip(O,[0x482092490482,0xd9cdff3b76cd,0x9bef5f3d978f])];n>>=4
print"\n".join(O)
d="3yy0nxcoypnk4185nbr3k9ddjlhe".to_i 36
s=gets.chomp
o=''
for i in 0..2
s.each_char{|c|q=d>>c.to_i(16)*3
"|_|".each_char{|z|o<<(q&1>0?z:' ')
q>>=1}}
d>>=48
o<<"\n"
end
puts o
И когда немного читабельнее ...
d="3yy0nxcoypnk4185nbr3k9ddjlhe".to_i 36
s=gets.chomp
o=''
for i in 0..2
s.each_char { |c|
q = d >> c.to_i(16) * 3
"|_|".each_char { |z|
o << (q & 1 > 0 ? z : ' ')
q >>= 1
}
}
d >>= 48
o << "\n"
end
puts o
Человек ... не может победить Perl. Вот какой-то py3k на 163 символа.
i=input()
[print(''.join(' | _ _|| | ||_ |_|'[(7&(d>>l))*3:][:3]for d
in[255&0xb4b61fa637bdbbbf89b7b3399b9e09af>>int(x,16)*8 for x in i]))for
l in[6,3,0]]
Объяснение. Сначала вот как это выглядело совершенно неоптимизированным:
# segment positions, easily understandable as octal. first digit is top row
# last digit is bottom row. high bit is first column, low bit last.
a=[0o257, 0o011, 0o236, 0o233,
0o071, 0o263, 0o267, 0o211,
0o277, 0o273, 0o275, 0o067,
0o246, 0o037, 0o266, 0o264]
# and the corresponding segments:
# 421 421 421 421 421 421 421 421
b=[' ', ' |', ' _ ', ' _|', '| ', '| |', '|_ ', '|_|']
# function to look for the proper segment for a decoded digit:
def lookup(digit, line):
return b[ 7& (digit>>(6-line*3))]
#function to encode an ascii hex string into coded form suitible for
#above function
def code(i):
return [a[int(x,16)] for x in i]
def fmt(i):
return '\n'.join(''.join(lookup(d,l) for d in code(i)) for l in [0,1,2])
i = input()
print(fmt(i))
Затем я ищу способы упаковать данные. Сначала я могу преобразовать a
в большое длинное целое число, сначала последний элемент, 8 бит за раз. Это дает в восьмеричном формате: 0o2645541764615736673577046675463463347404657
. записано в шестнадцатеричном формате, это 0xb4b61fa637bdbbbf89b7b3399b9e09af
, на 90 символов короче, чем список восьмеричных чисел. Конечно, чтобы использовать его, вам придется переписать код. Похоже, что
def code_a_8(i):
return [255&a_8>>int(x,16)*8 for x in i]
b
можно объединить, ''. Join (b)
- это 26 символов, включая кавычки. функция поиска также должна измениться, чтобы поддерживать это.
def lookup_b_cat(d, l):
return b_cat[(7&(d>>6-l*3))*3:][:3]
Затем я просто устраняю весь ненужный синтаксис, складывая функции и константы в выражение, и это почти все.
Можно также немного сократить печать. Вместо того, чтобы соединять строки, сразу же их распечатайте. это приводит к измененному fmt ()
:
def fmt_print(i):
[print(''.join(lookup(d,l) for d in code(i))) for l in [0,1,2]]
Исполняемый файл COM: 102 байта
Соберите следующее, используя A86 (это исходная, увеличенная версия):
dd 0801E8Ah,0BD80C380h,03B50154h,0D789D58Ah,0B20082BEh,077F33B03h,0C048A29h,0149F0420h
dd 020AD431h,088C402C4h,01468BC1h,0F8C1E0D3h,046220Fh,0AA036E8Dh,0DD75CAFEh,04609ED83h
dd 0C583D1EBh,0D0AB809h,075CDFEABh,0AA24B0C3h,021CD09B4h,05F0000C3h,020B7EBh,8EFB7C00h
dd 07C3EF75Fh,0BF7CF9E4h,0B6DE5FA2h
dw 0F47Ch
db 0DFh
Изменить:
Проблема с DosBox вероятно, так программа принимает значения регистров при запуске. В любом случае, вот модифицированный исходный код, который объединяется в 102 байта и должен работать с DosBox:
mov bp,d1
mov ch,3
mov dx,ds ; if you want to use dos box, put "mov dx,08000h" here instead, it might fix the problem
mov di,dx
l4: mov si,082h
l3: mov bl,3
cmp byte ptr [si],0dh
je l5
mov cl,[si]
cmp cl,40h
jle l2
add cl,9
l2: and cl,0fh
l1: mov ax,word ptr [bp+1]
shl ax,cl
sar ax,15
and al,byte ptr [bp]
add bp,3
stosb
dec bl
jnz l1
sub bp,9
inc si
jmp l3
l5: add bp,9
mov ax,0d0ah
stosw
dec ch
jnz l4
mov al,'$'
stosb
mov ah,9
int 21h
d1: ret
dw 0
db '_'
dw 01011011111101011xb
db ' '
dw 0
db '|'
dw 01000111011111011xb
db '_'
dw 00011111011110111xb
db '|'
dw 01111100111100100xb
db '|'
dw 01010001010111111xb
db '_'
dw 01011011011011110xb
db '|'
dw 01101111111110100xb
Спасибо ephemient за пару настроек!
char*q,a=3;p(l){putchar(*q?"|#]u&rzc~vn:X=ZJ"[*q-(*q&64?55:48
)&15]+1>>l&1?"|_||_|_"[l]:32:10);}main(r,v)char**v;{for(;a--
;p())for(q=v[1];*q;++q)for(r=3;r--;)p(a-2?5-r-a*3:r-1?7:6);}
stdin
)char*q,b[9],gets(char*),a=3;p(l){putchar(*q?"|#]u&rzc~vn:X=ZJ"[*
q-(*q&64?55:48)&15]+1>>l&1?"|_||_|_"[l]:32:10);}main(r){for(gets
(b);a--;p())for(q=b;*q;++q)for(r=3;r--;)p(a-2?5-r-a*3:r-1?7:6);}
Explanation:
char*q,b[9],gets(char*),a=3;
p(l){
putchar(*q?
/*
* Each element of the magic string is decremented so 0x7F is
* '~' (0x7E). Each bit before the decrement represents
* a segment (thus "8" is 0x7F (0x7E), i.e. all 7 bits on).
* Bit 7 is always cleared so p(7) always prints a space.
*/
"|#]u&rzc~vn:X=ZJ"
[*q-(*q&64?55:48)&15]+1 /* d[ascii2hex(*q)] + 1 */
>>l&1 /* Is bit 'l' set? */
?"|_||_|_"[l] /* Yes; choose _ or | by position. */
:32 /* No; enter a space. */
:10); /* End of line. */
}
main(r){
for(gets(b);a--;p()) /* Grab input and loop through each of 3 lines (a = 2, 1, 0). */
for(q=b;*q;++q) /* Iterate across input. */
for(r=3;r--;) /* For each of three characters across... */
p(a-2?5-r-a*3:r-1?7:6); /* Print the segment, mapping position to the bit. */
}
Я не сделал ничего умного, но все равно получил приличную оценку.
let rec G s=for r in[" _ _ _ _ _ _ _ _ _ _ _ _ ";"| | | _| _||_||_ |_ ||_||_||_||_ | _||_ |_ ";"|_| ||_ _| | _||_| ||_| _|| ||_||_ |_||_ | "]do Seq.iter(printf"%s"<<S r)s;printfn""
and S a h=a.Substring(3*(int h-if h<'A'then 48 elif h<'a'then 55 else 87),3)
С пробелом для ясности:
let rec G s=
for r in[" _ _ _ _ _ _ _ _ _ _ _ _ ";
"| | | _| _||_||_ |_ ||_||_||_||_ | _||_ |_ ";
"|_| ||_ _| | _||_| ||_| _|| ||_||_ |_||_ | "] do
Seq.iter (printf "%s" << S r) s;
printfn""
and S a h=
a.Substring(3*(int h - if h<'A'
then 48
elif h<'a'
then 55
else 87),3)
Пример:
G("abcdefFEDCBA9876543210")
Вывод:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|_||_ | _||_ |_ |_ |_ _|| |_ |_||_||_| ||_ |_ |_| _| _| || |
| ||_||_ |_||_ | | |_ |_||_ |_|| | _||_| ||_| _| | _||_ ||_|
i,j;main(c,s){char**r=s,*p=*++r;for(;i<3;)j--?putchar(!p[-1]?p=*r,++i,j=0,10:
"##3#3133X=W.<X/`^_G0?:0@"[i*8+c/2]-33>>c%2*3+j&1?"|_"[j&1]:32):(j=3,c=*p++&31,
c-=c>6?10:1);}
This takes the input string as a command-line argument. Conversion to use stdin would be one more character:
i,j;main(c){char s[99],*p=s;for(gets(s+1);i<3;)j--?putchar(!*p?p=s,++i,j=0,10:
"##3#3133X=W.<X/`^_G0?:0@"[i*8+c/2]-33>>c%2*3+j&1?"|_"[j&1]:32):(j=3,c=*++p&31,
c-=c>6?10:1);}
The stdin version can accept up to 98 input characters. Of course, any more than floor(terminalWidth / 3)
will cause confusing line wrap.
The output for each character is treated like a 3x3 grid, where the cells in each row are the segments. A segment is either "on" or "off". If a segment is "on", either a '|'
or a '_'
is output, depending on position. If it's off, a space is output. The character array is an array of bits that determine whether each segment is on or off. More about that after the code:
i,j; /* Loop variables. As globals, they'll be initialized to zero. */
main(c,s){
/* The signature for main is
*
* main(int argc, char **argv)
*
* Rather than add more characters for properly declaring the parameters,
* I'm leaving them without type specifiers, allowing them to default to
* int. On almost all modern platforms, a pointer is the same size as
* an int, so we can get away with the next line, which assigns the int
* value s to the char** variable r.
*/
char**r=s,*p=*++r;
/* After coercing the int s to a char** r, offset it by 1 to get the
* value of argv[1], which is the command-line argument. (argv[0] would
* be the name of the executable.)
*/
for(;i<3;) /* loop until we're done with 3 lines */
j--?
/* j is our horizontal loop variable. If we haven't finished a
* character, then ... */
putchar( /* ...we will output something */
!p[-1]? /* if the previous char was a terminating null ... */
p=*r,++i,j=0,10
/* ... reset for the next row. We need to:
*
* - reinitialize p to the start of the input
* - increment our vertical loop variable, i
* - set j to zero, since we're finished with this
* "character" (real characters take 3 iterations of
* the j loop to finish, but we need to short-circuit
* for end-of-string, since we need to output only one
* character, the newline)
* - finally, send 10 to putchar to output the newline. */
:"##3#3133X=W.<X/`^_G0?:0@"[i*8+c/2]-33>>c%2*3+j&1?
/* If we haven't reached the terminating null, then
* check whether the current segment should be "on" or
* "off". This bit of voodoo is explained after the
* code. */
"|_"[j&1]:32
/* if the segment is on, output either '|' or '_',
* depending on position (value of j), otherwise,
* output a space (ASCII 32) */
)/* end of putchar call */
:(j=3,c=*p++&31,c-=c>6?10:1);
/* this is the else condition for j--? above. If j was zero,
* then we need to reset for the next character:
*
* - set j to 3, since there are three cells across in the grid
* - increment p to the next input character with p++
* - convert the next character to a value in the range 0–15.
* The characters we're interested in, 0–9, A–F, and a–f, are
* unique in the bottom four bits, except the upper- and
* lowercase letters, which is what we want. So after anding
* with 15, the digits will be in the range 16–25, and the
* letters will be in the range 1–6. So we subtract 10 if
* it's above 6, or 1 otherwise. Therefore, input letters
* 'A'–'F', or 'a'–'f' map to values of c between 0 and 5,
* and input numbers '0'–'9' map to values of c between
* 6 and 15. The fact that this is not the same as the
* characters' actual hex values is not important, and I've
* simply rearranged the data array to match this order.
*/
}
The character array describes the character grids. Each character in the array describes one horizontal row of the output grid for two input characters. Each cell in the grid is represented by one bit, where 1
means that segment is "on" (so output a '|'
or a '_'
, depending on position), and 0
means that segment is "off".
It takes three characters in the array to describe the entire grid for two input characters. The lowest three bits of each character in the array, bits 0-2, describe one row for the even input character of the two. The next three bits, bits 3-5, describe one row for the odd input character of the two. Bits 6 and 7 are unused. This arrangement, with an offset of +33, allows every character in the array to be printable, without escape codes or non-ASCII characters.
I toyed with several different encodings, including putting the bits for all 7 segments of an input character into one character in the array, but found this one to be the overall shortest. While this scheme requires 24 characters in the array to represent the segments of only 16 input characters, other encodings either required using non-ASCII characters (which unsurprisingly caused problems when I used this in my Morse Code golf answer), a lot of escape codes, and/or complex decoding code. The decoding code for this scheme is surprisingly simple, although it does take full advantage of C's operator precedence to avoid having to add any parentheses.
Let's break it into tiny steps to understand it.
"##3#3133X=W.<X/`^_G0?:0@"
This is the encoded array. Let's grab the appropriate character to decode.
[i*8
The first 8 characters describe the top row of segments, the next 8 describe the middle row of segments, and the last 8 describe the bottom row of segments.
+c/2]
Remember that, by this point, c contains a value from 0 to 15, which corresponds to an input of ABCDEF0123456789, and that the array encodes two input characters per encoded character. So the first character in the array, '#'
, holds the bits for the top row of 'A' and of 'B', the second character, also '#'
, encodes the top row of 'C' and 'D', and so on.
-33
The encoding results in several values that are under 32, which would require escape codes. This offset brings every encoded character into the range of printable, unescaped characters.
>>
The right shift operator has lower precedence than arithmetic operators, so this shift is done to the character after subtracting the offset.
c%2*3
c%2
evaluates to zero for even numbers, and to one for odd numbers, so we'll shift right by three for odd characters, to get at bits 3–5, and not shift at all for even characters, providing access to bits 0–2. While I'd prefer to use c&1
for even/odd check, and that is what I use everywhere else, the &
operator has too low precedence to use here without adding parentheses. The %
operator has just the right precedence.
+j
Shift by an additional j
bits to get at the correct bit for the current output position.
&1
The bitwise and operator has lower precedence than both the arithmetic operators and the shift operators, so this will test whether bit zero is set after shifting has brought the relevant bit into bit zero.
?
If bit zero is set ...
"|_"
... output one of these characters, chosen by ...
[j&1]
... whether our horizontal loop variable is even or odd.
:32
Otherwise (bit zero is not set), output 32 (space character).
I don't think I can trim this down much more, if any, and certainly not enough to beat hobbs's perl entry.
На основе Джонаса Галла в Code Golf: The wave . Обычно я пишу 32-битный Linux ELF, но 16-битный DOS COM намного меньше (более короткие инструкции, нулевые накладные расходы).
46 инструкций и 24 невыполненных слова. (Они действительно явно выделяются в конце, не так ли? разве они?) Нет ничего сложнее, чем повторное использование кода в качестве данных; в любом случае он, вероятно, не сэкономит больше 10 байт.
C:\>od -xAn ss.com c930 82be ac00 0d3c 3e74 403c 027e 0904 0f24 0198 bbc8 0162 c301 0eb4 078a 0424 0474 7cb0 02eb 20b0 10cd 078a 0224 0474 5fb0 02eb 20b0 10cd 078a 0124 0474 7cb0 02eb 20b0 10cd bdeb f980 7420 b014 cd0d b010 cd0a 6610 c381 0010 0000 c180 eb10 c3a1 0002 0202 0200 0202 0202 0002 0002 0202 0105 0303 0607 0106 0707 0607 0304 0606 0107 0306 0301 0107 0307 0705 0706 0406 C:\>ss deadbeef _ _ _ _ _ _||_ |_| _||_ |_ |_ |_ |_||_ | ||_||_||_ |_ |
Это просто побуквенная печать первой строки, затем второй строки и т. д. с использованием 3 байтов для хранения 9 бит данных для каждого символа. Очевидно, еще есть место для улучшения… (Я впервые использую синтаксис NASM ; я больше привык к газу , но не смог убедить его выводить необработанный двоичный файл.)
org 0x100
; initialize registers
xor cl,cl
; reset ds:[si] to start of arguments
start:
mov si,0x82
; load one character of arguments
read:
lodsb
cmp al,0xd
je next
; transform [0-9A-Fa-f] to [\x00-\x0f]
cmp al,0x40
jle skipa
add al,0x9
skipa:
and al,0xf
; load font definition
cbw
add ax,cx
mov bx,letters
add bx,ax
mov ah,0xe
; print first char
mov al,[bx]
and al,0x4
jz s1
mov al,0x7c
jmp short w1
s1:
mov al,0x20
w1:
int 0x10
; print second char
mov al,[bx]
and al,0x2
jz s2
mov al,0x5f
jmp short w2
s2:
mov al,0x20
w2:
int 0x10
; print third char
mov al,[bx]
and al,0x1
jz s3
mov al,0x7c
jmp short w3
s3:
mov al,0x20
w3:
int 0x10
; next character
jmp short read
; print newline
next:
cmp cl,0x20
je end
mov al,0xd
int 0x10
mov al,0xa
int 0x10
add ebx,0x10
add cl,0x10
jmp short start
end:
ret
letters:
db 2,0,2,2,0,2,2,2,2,2,2,0,2,0,2,2
db 5,1,3,3,7,6,6,1,7,7,7,6,4,3,6,6
db 7,1,6,3,1,3,7,1,7,3,5,7,6,7,6,4
Трудно превзойти специализированный язык вроде Perl. Однако здесь версия Python в 160 байт :
i=input().lower()
for x in[' #_ 14bd# ','| 1237d#_ 017c#| 56bcef','| 134579#_ 147af#| 2cef']: print(' '.join(''.join(y[j in y]for y in x.split('#'))for j in i))
Версия без поддержки:
input_ = input().lower()
for magic in [' #_ 14bd# ',
'| 1237d#_ 017c#| 56bcef',
'| 134579#_ 147af#| 2cef',
]:
# We have three lines, so x iterates over 3 magic strings.
print(' '.join(
# This is the cycle iterating over digits.
''.join(
# For each line and digit we need to print several
# letters. To do this, we break a magic string into
# 3 chunks. A chunk usually contains digits that
# *don't* have an element there.
chunk[digit in chunk]
# For example, lower right chunk y="| 2cef". For digits
# 2, c, e, f, there should be " ", for all others there
# should be "|". So for digits 2, c, e, f, `j in y` returns
# False and indexes y[0], for other digits it indexes y[1].
for chunk in magic.split('#'))
for digit in input_))
$d=str_split(' _ | ||_ |_| _| || 124066153155046135134166144145142034173054133137',3);
foreach(str_split(strtolower($s))as$c){
$c=hexdec($c)+8;$r[0].=$d[$d[$c][0]];$r[1].=$d[$d[$c][1]];$r[2].=$d[$d[$c][2]];i
}
echo implode("\n",$r);
# Array containing possible lines
$d=array(
0 => ' ',
1 => ' _ ',
2 => '| |',
3 => '|_ ',
4 => '|_|',
5 => ' _|',
6 => ' |',
7 => '| '
);
# Array mapping characters to 3 lines
$m=array(
0 => '124', # i.e. The character '0' is represented by $d[1], $d[2] and $d[4]
1 => '066',
2 => '153',
3 => '155',
4 => '046',
5 => '135',
6 => '134',
7 => '166',
8 => '144',
9 => '145',
a => '142',
b => '034',
c => '173',
d => '054',
e => '133',
f => '137',
);
# traverse $s and append to array $r
foreach (str_split(strtolower($s)) as $c) {
$r[0].=$d[$m[$c][0]];
$r[1].=$d[$m[$c][1]];
$r[2].=$d[$m[$c][2]];
}
# echo $r
echo implode("\n",$r);
Оптимизация:
str_split ()
hexdec ()
Javascript 333 символа при упаковке
s=" ";
function r(p)
{
if(t[p]=="0")
return s;
return "_|_||_|".split("")[p];
}
function g(w){
a="";b=a;c=a;
z=[];
for(x=0;x<w.length;x++){
t=("000"+parseInt("6F095E5B397377497F7B7D37661F7674".substr(parseInt(w.substr(x,1),16)*2,2),16).toString(2)).slice(-7).split("");
a+=s+r(0)+s+s;
b+=r(1)+r(2)+r(3)+s;
c+=r(4)+r(5)+r(6)+s;
}
return a+"\n"+b+"\n"+c;
}
alert(g("0123456789deadbeef"));
$ echo -n deadbeef | ./golfscript.rb led.gs
_ _ _ _ _
_||_ |_| _||_ |_ |_ |_
|_||_ | ||_||_||_ |_ |
Убедитесь, что вы сохранили без дополнительной новой строки в конце, иначе входная строка будет напечатана в конце.
{32:^|}%:
{^' _':$@'14bd'{?~!=}:&~^}%n
{:x' |':|\'1237d'&$x'017c'&|x'56bcef'&}%n
{:x|\'134579'&$x'147af'&|x'2cef'&}%
Как это работает
Обратите внимание, что больше сегментов включено, чем выключено для диапазона 0-F. Перечислите исключения (цифры, по которым сегмент отключен) для каждого сегмента.
#Python version of the algorithm above
s=raw_input().lower()
J=''.join()
print J(' '+'_ '[c in'14bd']+' 'for c in s)
print J('| '[c in'1237d']+'_ '[c in'017c']+'| '[c in'56bcef']for c in s)
print J('| '[c in'134579']+'_ '[c in'147af']+'| '[c in'2cef']for c in s)
Немного поздно, но dc
запись, почти соответствующая спецификации: она принимает только числа в верхнем регистре, например [0-9A-F], и может печатать дополнительные 0 в начале. В любом случае, вот оно:
16iD9B4FE55FFBDFFA5BF5BAB774977sK
[ ][ _ ][ |][ _|][| ][|_ ][| |][|_|]8[1-ds_:al_d0<L]dsLx
?dsNZdsZ
40sr[[1-dlNr10r^/10%80r^lKr/80%lr/8%;aPd0<L]dsLxAP]dsAx
lZ8srlAxlZ1srlAx
Небольшое пояснение (разрывы строк не требуются):
Константа 0xD9B4FE55FFBDFFA5BF5BAB774977 кодирует каждую цифру в 7 битах, например число '4' кодируется как 0 111 010, что означает использование строки '0' для верха (''), строки 7 для середины ('
| _ |
') и строки. 2 для нижней части (' |
').
Вторая строка определяет строки и сохраняет их в массиве 'a'
Третья строка обрабатывает ввод и проверяет длину числа.
Четвертая строка выполняет вычисления. Он создал «подпрограмму» A и выполнил ее для первой строки. Подпрограмма извлекает соответствующую цифру ( 1-dlNr10r ^ / 10
), затем извлекает 7-битные данные кодирования ( 80r ^ lKr / 80%
), затем берет соответствующую часть для конкретная строка ( lr / 8%
) загружает строку и печатает ее (; aP
), затем она перебирает все цифры ( d0
Последняя строка делает то же самое для строк 2 и 3 дисплея.
val a=Seq("|_|"," _ "," |","| |"," _|","| ","|_ "," ")
val m=argv(0).toLowerCase.map(_-'0').map(i=>if(i<10)i else i-39)
for(s<-Seq(0,16,32))
println(m.map(i=>a("171171111117171132440662000654660264240204306065"(i+s)-'0')).mkString)
Код довольно прост: все 9 возможных сегментов упакованы в массив и отображаются между шестнадцатеричным числом и позицией. Наверное, можно было бы лучше упаковать.
Код для вычисления магических чисел:
val s = " _ _ *all numbers in one line here* |_||_ | "
val gl = (0 to s.size / 3-1).map(c => s.substring(c*3, c*3+3 ))
// gl now contains flat list of string of 3 chars each
val arr=gl.toSet.toArray // remove duplicates
// for each segment string find corresponding packed index
val n = gl.map( arr indexOf _).mkString
как результат, n - магическое число, arr - массив строк
Я начал с этого на (сейчас закрытом) гольф-коде цифровых часов, так что: также поддерживается. Todo: обрабатывать строчные буквы.
-[>+<-----]->----[>,]<[<]>>[[->]<+[-<+]->]<+>-[>]+++[[<]>>[[>]>[>]+[<]<[<]+[>]>[
>]+[-<+]->[[>]>[>]<+[<]<[<]>+[>]+[-<+]->-]->]<[<]>+[-[>]+[-<+]+<[<]>[[>]+[-<+]->
+<[<]>-]>+]+[-->]+[->]-[>-<-----]>+++>-->->----<<<[>>+++>+++++>-[+++<]>]-<+[>]-[
<]>>>+[-<<+[->+]<<-[-[++>->>[>]>>+++++>>+++++>>>>>+++++>>>+++++++>>>>>>+++++>>>+
++++>>+[<+]<[<]<]>[-<++>>>[>]<--->+>+>->++++++>+>-->>>>>>>+++>-->-->>+>+>-->->->
>+++++>+[<++++]<[<]]<]>[-<+>>>[>]<--->++++++>+>-->+>-->+++++>>>>>>>+++>->-->>-->
->>->+>>-->+[<++++]<[<]]<+>-[[>]>[>]<[-]<[<]<[<]>-]>[>]>[>]+<-[-[-[-[-[-[-[-[-[[
<]<<.>...>>[>]<-]>[<+[<]<<.>.<.>.>>[>]<->]<]>[<+[<]<..>>[>]<->]<]>[<+[<]<<<<.>>>
.>>[>]<->]<]>[<+[<]<....>>[>]<->]<]>[<+[<]<<.<.>>..>>[>]<->]<]>[<+[<]<..<.>.>>[>
]<->]<]>[<+[<]<.<<.>.>.>>[>]<->]<]>[<+[<]<<.<.>.>.>>[>]<->]<]>[<+[<]<.<<.>>..>>[
>]<->]<<[[-]<]-[<]>>>+]++++++++++.[>]<[[-]<]+[-<+]-[>]<-]
$ echo 01:23456789DEADBEEF | beef clock.b
_ _ _ _ _ _ _ _ _ _ _ _ _
| | | . _| _| |_| |_ |_ | |_| |_| _| |_ |_| _| |_ |_ |_ |_
|_| | . |_ _| | _| |_| | |_| _| |_| |_ | | |_| |_| |_ |_ |
Это сильно зависит от того, является ли платформа 8-битной.