画出这个Ascii咖啡杯:
Ø Ø Ø __________ / \ __ | J | \ | A | | | V | | | A | __ / \ __________ /
咖啡脚本或Java的布朗尼点:)
以字节,函数或程序为单位的最短代码,结尾的换行符或空格是可以接受的,多喝点!
画出这个Ascii咖啡杯:
Ø Ø Ø __________ / \ __ | J | \ | A | | | V | | | A | __ / \ __________ /
咖啡脚本或Java的布朗尼点:)
以字节,函数或程序为单位的最短代码,结尾的换行符或空格是可以接受的,多喝点!
Answers:
mγmλ⁶…Jcēņ▒&↓¡℮štΥ{ιE‽▼⅛÷εγ╝Ξ∫$■⌡πθ&χF׀▼ΡQ7L↓F¶‘
说明:
SOGL具有内置的字符串压缩功能,其中之一是char字典压缩。更好的是,它具有boxstring压缩类型,其中唯一可用的字符是“ / \ | _- \ n”。因此,整个程序是一个用“'括起来的字符串(”是隐式的)。
我给压缩程序的字符串是(转义的):
" o\n o\n o\n ",
"__________",
"\n/ \\__\n| ",
"J",
" | \\\n| ",
"A",
" | |\n| ",
"V",
" | |\n| ",
"A",
" |__/\n\\",
"__________",
"/"
由于edc65,节省了4个字节
let f =
_=>`1o
6o
3o
9
/44\\__
|2J5|1\\
|3A4|1|
|4V3|1|
|5A2|__/
\\9/`.replace(/\d/g,n=>' _'[n>>3].repeat(++n))
console.log(f())
通过用一位数字替换2到10个连续空格的所有序列以及10个连续下划线的两个序列,可以实现原始ASCII技术的压缩:
N
连续空格的每个序列都用digit编码N-1
。9
。我们使用N-1
而不是而不是N
使用一个以上的数字。因此需要++n
解码时。
表达式n>>3
(向右逐位移位)对等于0,n = 1
对n = 7
和n = 8
(不使用)等于1 n = 9
。因此,请' _'[n>>3]
为提供下划线9
,并为所有其他遇到的值提供一个空格。
唯一的特殊情况是在“ JAVA”上方的10个连续空格的序列。用a编码9
会与下划线序列冲突。因此,我们需要将其分成5个空格的两个序列,编码为44
。
f=
)。您可以这样保存4个字节:n>>3
代替+!(n&7)
,9
代替_8
(两次),44
而不是9
f=
那个...感谢您保存的字节!
' '
)。但是不确定到底是怎么做到的。移位有什么作用?为什么我们要递增n?
-2个字节归功于Dennis(1.删除冗余 ”
,并2.替换转置和游程长度解码ZŒṙ
,用减少元素重复数来代替x/
。)
“Ñṁ{xGgṭḷVỤɲ8ṿfƬT9Ɱ¹=qṀS“$<(ƇỤ08ØÑḌṃṘX6~cuc8HṗḞ2’Dx/ị“ ¶_/\|JAVo
“...“...’
是两个以250为基数的压缩数字的列表:
[1021021021332411532617161526181616261916162618163425334, 2117114111551155121131612111415121115141211161312111551]
D
转换为十进制以产生两个数字列表:
[[1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 3, 3, 2, 4, 1, 1, 5, 3, 2, 6, 1, 7, 1, 6, 1, 5, 2, 6, 1, 8, 1, 6, 1, 6, 2, 6, 1, 9, 1, 6, 1, 6, 2, 6, 1, 8, 1, 6, 3, 4, 2, 5, 3, 3, 4], [2, 1, 1, 7, 1, 1, 4, 1, 1, 1, 5, 5, 1, 1, 5, 5, 1, 2, 1, 1, 3, 1, 6, 1, 2, 1, 1, 1, 4, 1, 5, 1, 2, 1, 1, 1, 5, 1, 4, 1, 2, 1, 1, 1, 6, 1, 3, 1, 2, 1, 1, 1, 5, 5, 1]]
x/
通过元素重复减少以给出一个数字列表(将第一个列表中的数字重复另一个数字的相应值):
[1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 3, 3, 2, 6, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 6, 1, 1, 5, 2, 6, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 6, 1, 1, 6, 2, 6, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 6, 1, 1, 6, 2, 6, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 6, 3, 3, 4, 2, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4]
ị
指示索引到右边的列表中,该列表是基于基础的和模块化的(最右边的项目中有0个索引)。右边的列表¶_/\|JAVo
只是按所需顺序使用的字符,其中,¶
是与换行符相同的代码点。的最终合伙人“
不需要因为这是程序的结尾:
[' ', ' ', 'o', '\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', '\n', ' ', ' ', ' ', ' ', 'o', '\n', ' ', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '\n', '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\\', '_', '_', '\n', '|', ' ', ' ', ' ', 'J', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '\\', '\n', '|', ' ', ' ', ' ', ' ', 'A', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', '\n', '|', ' ', ' ', ' ', ' ', ' ', 'V', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', '\n', '|', ' ', ' ', ' ', ' ', ' ', ' ', 'A', ' ', ' ', ' ', '|', '_', '_', '/', '\n', '\\', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '/']
Jelly执行此列表的隐式打印,由于该列表包含字符,因此将其视为字符串进行打印:
o
o
o
__________
/ \__
| J | \
| A | |
| V | |
| A |__/
\__________/
”
是隐式的,可以替换ZŒṙ
为x/
。另外,尽管它没有任何字节,但使用¶
而不是文字换行符会使代码更易于修改imo。
r="replace";" 1o0n0 6o0n0 3o0n0 _9n0/0 9b0_1n0|0 2J0 5|0 1b0n0|0 3A 4|0 1|0n0|0 4V0 3|0 1|0n0|0 5A0 2|0_1/0n0b0_9/0"[r](/\d/g,(a,b,c)->c[b-1].repeat(a))[r](/n/g,"\n")[r](/b/g,"\\")
f=()->""" o
o
o
__________
/ \__
| J | \\
| A | |
| V | |
| A |__/
\__________/"""
没有硬编码。
没有Base-64编码。
没有正则表达式。
k=' '
q='_'*10
print'\n'.join([k*i+'o'for i in 2,7,4]+[k+q]+['/'+k*10+'\\__']+['|'+k*s+'JAVA'[s-3]+k*(9-s)+'|'+' _'[s==6]*2+'\\||/'[s-3]for s in 3,4,5,6]+['\\'+q+'/'])
通过外部化'_'*10
和利用Python对True -> 1
and 的转换节省了2个字节False -> 0
。
通过删除不必要的空格节省了1个字节。
感谢@TuukkaX,节省了4个字节!
] for
和处有2个无用的空格in [
。
[2,7,4]
,并[3,4,5,6]
以2,4,7
和3,4,5,6
。
"""2o
7o
4o
$(($a='_'*10))
/55\__
|3J6|2\
|4A5|2|
|5V4|2|
|6A3|__/
\$a/"""-replace'(\d)','$(" "*$1)'|iex
感谢@briantist找到较短的 -replace
我知道某个地方存在方法。
这将带数字的字符串替换为必需的空格数。然后,我们-replace
用脚本表达式对数字进行正则表达式$(" "*$1)
。因此,例如,字符串的第一行将为$(" "*2)o
,第二行将$(" "*7)o
以此类推。由于使用三重引号,因此将其作为字符串留在管道中。我们将其转储到iex
(是的缩写Invoke-Expression
,类似于eval
),后者处理脚本表达式并将结果的多行字符串留在管道上。输出是隐式的。
($_,' '*$_)[+$_-in48..57]
-不管我进行什么更改,它似乎对我来说都是失败的。
s:$: o@SS o@S o@ UU@/SSS \\__@|SJSS| \\@|S AS | |@|S VS | |@|SSAS|__/@\\UU/:
s:S: :g
y:@:\n:
s:U:_____:g
基本编码,它存储3位的S
,\n
因为@
和5下划线的U
。我将继续尝试组合以找到更短的内容。
下面给出直接打印字符串的简单解决方案。使用上面的编码方案,它有136个字节,压缩率为18%。
c\ o\
o\
o\
__________\
/ \\__\
| J | \\\
| A | |\
| V | |\
| A |__/\
\\__________/
S
存储3个空格,否s
。我想我将编辑它,因为它保留相同数量的转换。
[TIH][IAC]111Z?c'(ty!(OWM4J4gW{lm> >bw8ch|.FU2W"@\#2Dj!NQDeIMZ'F'_ /|\JAV'Za7e
该解决方案将咖啡分为两部分:“气泡”和杯子。为了创建气泡,我们在三个位置创建一个稀疏矩阵,其中包含111,并将其转换为字符数组
[TIH][IAC]111Z?c
对于杯子组件,我们依靠字符串压缩
'(ty!(OWM4J4gW{lm> >bw8ch|.FU2W"@\#2Dj!NQDeIMZ'F'_ /|\JAV'Za7e
两个组件都打印到输出,并且在组件之间自动放置换行符
在MATL Online上尝试
-1字节归功于Rod(使用元组的乘法('_'*10,)
来避免声明)。
print''.join('0'<c<':'and' '*int(c)or c for c in'''2o
7o
4o
%s
/ 9\__
|3J6|2\\
|4A5|2|
|5V4|2|
|6A3|__/
\%s/'''%(('_'*10,)*2))
注:该双反斜线被换行之前需要。
'''
和之间的所有内容'''
都是一个字符串,这两个%s
是格式化程序,它们被尾随的%(...)
元组的内容所取代,尾随的元组又包含'_'*10
通过元组乘法的两个副本(...)*2
。所述'_'*10
执行串相乘,以产生'__________'
。
该代码遍历,人物c
,是整串的使用for c in '''...
,并通过加入创建一个新字符串(join(...)
)
或者通过识别空格数c
,int(c)
如果c
是一个数字
或 c
本身
-是一个数字被确定'0'<c<':'
保存了c.isdigit()
。
u,u
用('_'*10,)*2
拖放的u
声明
打高尔夫球:
()->{String s="";for(char c:"\u026F\n\u076F\n\u046F\n __________\n/\u0A5C__\n|\u034A\u067C\u025C\n|\u0441\u057C\u027C\n|\u0556\u047C\u027C\n|\u0641\u037C__/\n\\__________/".toCharArray()){for(int i=0;i<c>>8;++i)s+=' ';s+=(char)(c&255);}return s;}
本着kolmogorov-complexity的精神,这不会对要输出的字符串进行硬编码。取而代之的是,它利用了许多情况下多个空格后跟可打印字符的事实。它用字符的高位字节编码字符前面的空格数,并用低位字节编码实际的ASCII字符。
取消高尔夫:
import java.util.function.*;
public class DrinkYourMorningCoffee {
public static void main(String[] args) {
System.out.println(f(
() -> {
String s = "";
for (char c : "\u026F\n\u076F\n\u046F\n __________\n/\u0A5C__\n|\u034A\u067C\u025C\n|\u0441\u057C\u027C\n|\u0556\u047C\u027C\n|\u0641\u037C__/\n\\__________/".toCharArray()) {
for (int i = 0; i < c >> 8; ++i) {
s += ' ';
}
s += (char) (c & 255);
}
return s;
}
));
}
private static String f(Supplier<String> s) {
return s.get();
}
}
\u0641
。
<v"XaXXXNYXNY77777'XXXXX2_TXQXX0XZTXDXX0X^TXXRX0X^TXXDX07]27777#"p29+55
:<_@#:,g2/+55,g2%+55
\JV/|_Ao
首先将字符串中的字符编码为十个可能值的查找表中的索引。然后将索引分为几对,每对被组合成一个0至99范围内的单个数字(i1 + i2 * 10)。通过仔细选择查找表的顺序,我们可以保证这些值将始终有效可以用字符串文字表示的ASCII字符。
这是代码本身的细分:
我们首先用换行符(ASCII 10)初始化查找表的最后一个元素。
然后,我们使用字符串文字将编码后的内容压入堆栈。
最后,我们遍历堆栈的值,一次解码并输出两个字符。
最后一行保存查找表:第9个元素是一个隐含空间,第10个(换行符)是手动设置的,如前所述。
(format t"~3@{~vto
~} ~10@{_~}
/~11t\\__
| J~11t| \\
~2@{|~5t~a~11t| |
~}|~7tA |__/
\\~10{_~}/"2 7 4'A" V"1)
我保存了6个字节,只是想将enters放入字符串而不是~&
s。
欢迎提出改进意见。
print(' o\n'+7*' '+'o\n'+4*' '+'o\n'+' '+10*'_'+'\n'+'/'+10*' '+'\__\n'+'|'+3*' '+'J'+6*' '+'| \\\n'+'|'+4*' '+'A'+5*' '+'| |\n'+'|'+5*' '+'V'+4*' '+'| |\n'+'|'+6*' '+'A'+3*' '+'|__/\n'+'\\'+10*'_'+'/')
s=' '
变量并使用它。
'o\n'
具有与相同的长度'o'+n
。
print(*(' o',7*' '+'o',4*' '+'o',' '+10*'_','/'+10*' '+'\__','|'+3*' '+'J'+6*' '+'| \\','|'+4*' '+'A'+5*' '+'| |','|'+5*' '+'V'+4*' '+'| |','|'+6*' '+'A'+3*' '+'|__/','\\'+10*'_'+'/'),sep='\n')
或for x in(' o',7*' '+'o',4*' '+'o',' '+10*'_','/'+10*' '+'\__','|'+3*' '+'J'+6*' '+'| \\','|'+4*' '+'A'+5*' '+'| |','|'+5*' '+'V'+4*' '+'| |','|'+6*' '+'A'+3*' '+'|__/','\\'+10*'_'+'/'):print(x)
两者都为197。仍然比136硬代码长。
广泛使用格式字符串的解决方案:
void f(){printf("%1$3c\n%1$8c\n%1$5c\n%2$11s\n/%3$13s\n|%4$4c%5$7c%6$3c\n|%7$5c%5$6c%5$3c\n|%8$6c%5$5c%5$3c\n|%7$7c%5$4c__/\n\\%2$s/\n",'o',"__________","\\__",74,'|',92,65,86);}
这是一个更具可读性的版本:
void f() {
printf("%1$3c\n"
"%1$8c\n"
"%1$5c\n"
"%2$11s\n"
"/%3$13s\n"
"|%4$4c%5$7c%6$3c\n"
"|%7$5c%5$6c%5$3c\n"
"|%8$6c%5$5c%5$3c\n"
"|%7$7c%5$4c__/\n"
"\\%2$s/\n"
'o',"__________","\\__",'J','|','\','A','V');
}
void g(){puts(" o\n o\n o\n __________\n/ \\__\n| J | \\\n| A | |\n| V | |\n| A |__/\n\__________/\n");}
该解决方案是使用此脚本自动生成的。
0 0o¶ 1¶/32\__¶4 J24\¶|3A 34|¶| 3V34|¶|2A |__/¶\1/
4
|
3
2
1
__________
0
o¶
(多行上有尾随空格)
通过使用数字1,2,3,4代替一些在目标字符串中重复的字符序列,然后将其替换回来,可以起作用。
我知道可以通过调整代码或完全改变方法来解决问题,但是由于kolmogorov元高尔夫挑战赛的结果令人失望,因此我想尝试将脚本用于实际挑战赛。
这是我对霍夫曼编码的尝试。如果有人想接受这个想法,那无疑是可以进一步发展的。
from bitarray import bitarray as b
a=b()
a.frombytes(bytes.fromhex('ca7fca7e53b6db6db664ffc6d9ae1fd6335e2fad1af83d68d7e2e9b218db6db6db20'))
print(''.join(a.decode({k:b(v)for k,v in zip(" _|\no/\\AJV","1 011 010 0011 00101 00100 00011 00010 00001 00000".split())})))
可以通过转换为base64或其他形式进一步压缩文字,并且可以优化霍夫曼树以产生更短的位数组。
f(){printf(" o\n%7co\n o\n __________\n/%11c__\n| J%6c| \\\n| A | |\n|%6c | |\n|%7c |__/\n\\__________/",0,92,0,86,65);}
main(){f();}
w(){puts(" o\n o\n o\n __________\n/ \\__\n| J | \\\n| A | |\n| V | |\n| A |__/\n\\__________/");}
for(;$c="1o
6o
3o
9
/44\\__
|2J5|1\\
|3A4|1|
|4V3|1|
|5A2|__/
\\9/"[$i++];)echo$c>0?str_repeat(" _"[$c>8],$c+1):$c;
这看起来很像Arnauld的答案 -几乎一样。用运行-r
。
()->{String s="";BigInteger b=new BigInteger("43ljxwxunmd9l9jcb3w0rylqzbs62sy1zk7gak5836c2lv5t36ej6682n2pyucm7gkm9bkfbn4ttn0gltbscvbttifvtdfetxorj6mmy3mt6r3",36);while(!b.equals(BigInteger.ZERO)){int x=b.intValue()&0x3ff;for(int i=0;i<x>>7;i++)s+=' ';s+=(char)(x&0x7f);b=b.shiftRight(10);}return s;}
取消高尔夫:
() -> {
String s = "";
BigInteger b = new BigInteger(
"43ljxwxunmd9l9jcb3w0rylqzbs62sy1zk7gak5836c2lv5t36ej6682n2pyucm7gkm9bkfbn4ttn0gltbscvbttifvtdfetxorj6mmy3mt6r3",
36);
while (!b.equals(BigInteger.ZERO)) {
int x = b.intValue() & 0x3ff;
for (int i = 0; i < x >> 7; i++) s+=' ';
s += (char)(x&0x7f);
b = b.shiftRight(10);
}
return s;
}
在JShell中的用法:
Supplier<String> golf = <lambda expression>
System.out.println(golf.get())
将每个字符编码为十位,由高三位字符前的空格数和低七位后的代码点组成。
(由于计数只有3位,因此不能表示超过七个连续的空格,并且字符串中的一点处有10个空格。这些编码为6个数字,后跟一个空格,然后是一个数3,然后是下一个字符。)
可悲的是,它失去了这个琐碎的140字节Java解决方案:
()->" o\n o\n o\n __________\n/ \\__\n| J | \\\n| A | |\n| V | |\n| A |__/\n\\__________/"