十行条形图


13

这是APL CodeGolf 秋季比赛 Hole-1 。我是该问题的原始作者,因此可以在此处重新发布。


给定一个数字列表,请生成一个水平的#字符条形图,以显示十个相等大小的组中每个组可容纳多少个数字。例如,如果数据的范围是0-100,则范围将是0–9.9、10–19.9,…,90–100。(通常为[0,10),[10,20),…,[90,100]。)您可能会假设至少会有两个数字,并且并非所有数字都相同。

例子:

[1,0,0,0,0,0,0,0,0,0] 给出:

#########








#        

[0,1,2,3,4,5,6,7,8,9] 给出:

#
#
#
#
#
#
#
#
#
#

[0,1,2,3,4,5,6,7,8,9,10] 给出:

#
#
#
#
#
#
#
#
#
##

[0,1,2,3,4,5,6,7,8,9,10,11] 给出:

##
#
#
#
#
#
#
#
#
##

[0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,-4.5,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,3,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,-1,4,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,4.5,4,3.5,3,2.5,2,1.5,1,0.5,0] 给出:

###                
#######            
###########        
###############    
#########          
###################
###############    
###########        
#######            
###                

[9014,9082,9077,9068,8866,8710,9049,8364,8867,9015,9064,9023,9024,8804,8805,8800,8744,8743,8714,9076,8593,8595,9075,9675,8968,8970,8711,8728,8834,8835,8745,8746,8869,8868,9073,9074,9042,9035,9033,9021,8854,9055,9017,9045,9038,9067,9066,8801,8802,9496,9488,9484,9492,9532,9472,9500,9508,9524,9516,9474,8739,9079,8900,8592,8594,9053,9109,9054,9059] 给出:

#                        
####                     
#########                
############             
######                   
#########################


###########              
#                        

[0,8,10,13,32,12,6,7,27,9,37,39,95,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,1,2,175,46,48,49,50,51,52,53,54,55,56,57,3,165,36,163,162,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,4,5,253,183,127,193,194,195,199,200,202,203,204,205,206,207,208,210,211,212,213,217,218,219,221,254,227,236,240,242,245,123,125,168,192,196,197,198,201,209,214,216,220,223,224,225,226,228,229,230,231,232,233,234,235,237,238,239,241,91,47,92,60,61,62,45,43,247,215,63,126,42,40,124,59,44,33,243,244,246,248,34,35,30,38,180,64,249,250,251,94,252,96,182,58,191,161,41,93,31,160,167] 给出:

#############             
######################    
##########################
######################### 
######################### 
#                         
########                  
################          
########################  
##########################

3
那么,最后一组要大一点吗?像第一个示例一样,它将是[0.9,1](而不是[0.9,1))?
菲利克斯·帕尔姆

@FelixPalmen有点。它只会无限小地增大。
亚当

好的,要知道的重要一点是,这确实是应该同时包括两个端点的最后一个小组,谢谢
Felix Palmen

@FelixPalmen啊,我知道在OP中还不是很清楚。我会对其进行编辑。
Adám17年

1
@Adám应该反向吗?顶行仅[0,1)包含,0而底行同时[9,10]包含910
user202729

Answers:




4

R77 81字节

+4个字节来修复一些测试用例

for(i in hist(x<-scan(),seq(min(x),max(x),,11),r=F)$c)cat(rep('#',i),'\n',sep='')

在线尝试!

链接是采用逗号分隔输入的代码版本。此版本以空格分隔。

从stdin读取,打印到stdout。

R是一种统计编程语言,它会尽力提供高质量的结果,有时这会令人沮丧:

hist将输入分类为直方图,breaks并将其作为第二个参数。通常,您会希望您可以将中断数指定为10。实际上,情况是这样的:

breaks

之一:

  • 给出直方图单元格之间的断点的向量,
  • 计算断点向量的函数,
  • 给出直方图的单元格数量的单个数字,
  • 命名算法以计算单元数的字符串(请参见“详细信息”),
  • 计算单元数的函数。

(强调)。

但是,下一句话说:

在后三种情况下,该数字仅是建议值;因为将断点设置为pretty值,所以该数目被限制为1e6(如果大于则发出警告)。

因此,我查看了的文档,pretty但它不适用于我们的情况,因为它因此选择了断点:

计算大约n+1等间距的“舍入”值的序列,该值覆盖中的值范围x。选择这些值以使它们是10的幂的1、2或5倍。

根本不会这样做。

因此,将seq(min(x),max(x),,11)11个等间距的点指定为breakshist(x,breaks,r=F)$c给出计数,r=F确保分档是右开间隔,然后for循环处理其余部分。


3

C(gcc),241字节

#define P(x)for(;x--;putchar('#'));puts("");
double a[999],u,l,x;i,j,n[9];main(k){for(;scanf("%lf",&x)>0;u=u>x?u:x,l=l<x?l:x,a[i++]=x);for(;j<i;++j)for(k=0;k<9;)if(a[j]<l+(++k)*(u-l)/10){n[k-1]++;break;}for(k=0;k<9;++k){i-=n[k];P(n[k])}P(i)}

在线尝试!


我认为您可以将k其设置为全局(+1字节),但是将其初始化为0,从而从中保存3个字节k=0
user202729 '17

您还可以切换doublefloatlff,再节省2个字节。(至少适用于TIO)
user202729 '17

@ user202729您的第一个评论:不,在外部循环内需要多次进行此初始化。float可能行得通,我没有使用它,因为它不是C语言中的“标准”浮点类型,并且降低了精度,因此不确定是否允许这样做...
Felix Palmen


3

Mathematica,152个字节

(Do[Print[""<>Table["#",Length@Select[s=#,Min@s+(t=#2-#&@@MinMax@s/10)(i-1)<=#<Min@s+t*i&]]],{i,9}];Print[""<>Table["#",Length@Select[s,Max@s-t<=#&]]])&


在线尝试!


应该如何运作?TIO仅具有文本输出。(回复“丹尼斯将修复此问题”部分)
user202729 '17

1
@ user202729您真的相信我不知道吗?或...
J42161217

2
不要冒犯您,但是您Range[0,9]在我无聊时提到Range[0,10]。但是它实际上失败了Range[0,10]TIO
user202729

4
<=在两端都使用过,这在最后一个段上正确,但在其他9个段上却不正确。
user202729

3
@ user202729嗨!这对我的帮助与您之前的Range [0,n] = {0,.. n}信息一样多。+1是个很好的建议。无论如何,代码现在可以正常工作
J42161217 '17

3

JavaScript(ES6),99个字节

编辑 2个字节保存thx @JustinMariner

一个返回字符串数组的函数

l=>l.map(v=>o[i=(v-n)/(Math.max(...l)-n)*10|0,i>9?9:i]+='#',o=Array(10).fill``,n=Math.min(...l))&&o

少打高尔夫球

list => {
   var max = Math.max(...list),
       min = Math.min(...list),
       output = Array(10).fill(''),
       index;

   list.forEach( value => (
      index = (value - min) / (max - min) * 10 | 0,
      output [index > 9 ? 9 : index] += '#'
   ) )
   return output
}

测试

var F=
l=>l.map(v=>o[i=(v-n)/(Math.max(...l)-n)*10|0,i>9?9:i]+='#',o=Array(10).fill``,n=Math.min(...l))&&o

var test=[
[1,0,0,0,0,0,0,0,0,0],
[0,1,2,3,4,5,6,7,8,9],
[0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,-4.5,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,3,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,-1,4,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,4.5,4,3.5,3,2.5,2,1.5,1,0.5,0],
[0,8,10,13,32,12,6,7,27,9,37,39,95,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,1,2,175,46,48,49,50,51,52,53,54,55,56,57,3,165,36,163,162,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,4,5,253,183,127,193,194,195,199,200,202,203,204,205,206,207,208,210,211,212,213,217,218,219,221,254,227,236,240,242,245,123,125,168,192,196,197,198,201,209,214,216,220,223,224,225,226,228,229,230,231,232,233,234,235,237,238,239,241,91,47,92,60,61,62,45,43,247,215,63,126,42,40,124,59,44,33,243,244,246,248,34,35,30,38,180,64,249,250,251,94,252,96,182,58,191,161,41,93,31,160,167],
[9014,9082,9077,9068,8866,8710,9049,8364,8867,9015,9064,9023,9024,8804,8805,8800,8744,8743,8714,9076,8593,8595,9075,9675,8968,8970,8711,8728,8834,8835,8745,8746,8869,8868,9073,9074,9042,9035,9033,9021,8854,9055,9017,9045,9038,9067,9066,8801,8802,9496,9488,9484,9492,9532,9472,9500,9508,9524,9516,9474,8739,9079,8900,8592,8594,9053,9109,9054,9059]];

output=x=>O.textContent+=x+'\n\n'

test.forEach(t=>output(t+'\n'+F(t).join`\n`))
<pre id=O></pre>


您应该可以通过将分配的赋值移动i到数组括号中并用逗号分隔来节省几个字节,从而允许您删除map函数主体周围的括号:在线尝试!
贾斯汀·马里纳

@JustinMariner对,谢谢
-edc65

如果您放弃i使用Math.min并再次使用,实际上可以再节省一个字节,并使用别名:在线尝试!
贾斯汀·马里纳

2

Python 2中126个 121字节

def f(a):
 m=min(a);r=range(10);A=[sum(x>=m+i*(max(a)-m)/10.for x in a)for i in r]+[0]
 for i in r:print'#'*(A[i]-A[i+1])

在线尝试!


2

果冻,21字节

单声道链接返回字符串列表。

_Ṃµ÷Ṁ×⁵Ḟµ<⁵+ċЀ⁵R¤”#ẋ

在线尝试!


尽管返回行列表是允许的,但显示的结果不会以任何方式分开。我不知道那是否有效。
user202729 '17

允许这样做,因为Jelly就是这样处理字符串列表的。您可以在页脚中添加ÇŒṘÇY以可视化结果。另外,您可以说您提交的是单子链接,而不是完整的程序,它返回而不是打印,从而自动生效。
Xcoder先生

2

Pyth 32  31字节

*R\#_M.++msmgk+JhSQ*dc-eSQJTQTZ

在这里尝试!验证所有测试用例。(使用的漂亮字体j

如何运作

这是一个完整程序,需要从STDIN输入。这是32字节的版本。我会尽快更新。

* R \ #_ M。++ msmgk + hSQ * dc-eSQhSQTQTZ〜完整程序

         m T〜用var d映射到[0,10)。
           m Q〜将输入映射为var k。
            g〜等于或大于?
             k〜输入的当前元素k。
              + hSQ * dc-eSQhSQT〜我们将其分解为几部分:
               hSQ〜输入列表的最低元素。
              +〜加:
                  * dc-eSQhSQT〜我们将分解为更多部分:
                  *〜乘法。
                   d〜[0,10),d的当前元素。
                    c T〜浮点除以10,其中:
                     -eSQhSQ〜最大值和最小值之差
                                        输入列表。
          s〜总和。计算真实结果的数量。
        + Z〜附加0。
      。+〜获取增量。
    _M〜为上面列表中的每个增量获取-delta。
  \#〜文字字符“#”。
* R〜向量化乘法。您也可以选择
                                    使用j通过换行符联接(如链接一样)。
                                  〜隐式输出。

2

木炭,31字节

≔I⪪S,θEχ×#ΣEθ⁼ι⌊⟦⁹⌊×χ∕⁻λ⌊θ⁻⌈θ⌊θ

在线尝试!链接是详细版本的代码。在Charcoal中,可变长度列表的输入似乎有点尴尬,因此我不得不将列表包装在包含字符串的数组中。说明:

   S                            Input string
  ⪪ ,                           Split on commas
 I                              Cast elements to integer
≔    θ                          Assign to variable q
      Eχ                        Map from 0 to 9
           Eθ                   Map over the list
                      ⁻λ⌊θ      Subtract the minimum from the current
                          ⁻⌈θ⌊θ Subtract the minimum from the maximum
                     ∕          Divide
                   ×χ           Multiply by 10
                  ⌊             Floor
               ⌊⟦⁹              Take minimum with 9
             ⁼ι                 Compare to outer map variable
          Σ                     Take the sum
        ×#                      Repeat # that many times
                                Implicitly print on separate lines

2

Fortran 2003,263个字节

我是在GNU gfortran 5.4.0上编写的,并且在编译时没有任何其他标志。

它一次从STDIN读取一个值,然后打印到STDOUT。

它去了:

程序h; real,allocatable :: a(:);字符f * 9; allocate(a(0)); do; read(*,*,end = 8)r; a = [a,r]; enddo; 9 format(“(”,i0,“(”“#”“))”)
8 a =(a-minval(a))+ epsilon(1。); a =天花板(10 * a / maxval(a)); do i = 1,10; j = count(a == i);如果(j == 0)print *;如果(j == 0)cycle; write(f,9)j;
打印f; enddo; end

非高尔夫的解释:(我不知道“高尔夫”是否可以应用于fortran,但是:P都可以)

程序h
真正的,可分配的:: a(:)!创建一个可分配的数组,以便我们可以动态地重新分配
字符f * 9!字符数组,用于格式化输出
分配(a(0))!首先分配“ a”为空
做
  读(*,*,end = 8)r!从STDIN阅读。如果是EOF,则转到8,否则
  a = [a,r]!附加到“ a”
尽头
9 format(“(”,i0,“(”“#”“))”)!格式标签
8 a =(a-minval(a))+ epsilon(1。)!(8)标准化a(添加epsilon以避免零索引)
a =天花板(10 * a / maxval(a))!归一化并乘以箱数
我= 1,10!在所有垃圾箱上循环播放
  j = count(a == i)!计算发生次数
  if(j == 0)print *!如果不存在,则打印空行
  if(j == 0)cycle!并跳过循环的其余部分
  写(f,9)j!否则将count(j)写入打印标签
  打印f!并打印到STDOUT
尽头
结束

有趣的事实:昨天我做了一个类似的代码来测试我的Weibull随机数生成器的实现,因此只需要一点改动即可:)




1

Perl 5,102字节

$l=(@n=sort{$a<=>$b}<>)[-1]-($f=$n[0]);$m=$f+$l*$_/10,say'#'x(@n-(@n=grep$_>=$m,@n))for 1..9;say'#'x@n

在线尝试

取消高尔夫:

my @n = sort { $a <=> $b } <>;
my $f = $n[0];
my $l = $n[-1] - $n[0];
for (1 .. 9) {
    my $m = $f + $l * ($_ / 10);
    my $c = scalar @n;
    @n = grep { $_ >= $m } @n;
    say('#' x ($c - scalar @n));
}
say('#' x scalar @n);


1

q / kdb +,52个字节

解:

{sum[t=/:bin[m+.1*(t:(!)10)*max[x]-m:min x;x]]#'"#"}

在线尝试!(请注意,TIO链接是此解决方案的44字节K(oK)端口,因为q / kdb +没有TIO。)

例子:

q){sum[t=/:bin[m+.1*(t:(!)10)*max[x]-m:min x;x]]#'"#"}1 0 0 0 0 0 0 0 0 0f
"#########"
""
""
""
""
""
""
""
""
,"#

q){sum[t=/:bin[m+.1*(t:(!)10)*max[x]-m:min x;x]]#'"#"}9014 9082 9077 9068 8866 8710 9049 8364 8867 9015 9064 9023 9024 8804 8805 8800 8744 8743 8714 9076 8593 8595 9075 9675 8968 8970 8711 8728 8834 8835 8745 8746 8869 8868 9073 9074 9042 9035 9033 9021 8854 9055 9017 9045 9038 9067 9066 8801 8802 9496 9488 9484 9492 9532 9472 9500 9508 9524 9516 9474 8739 9079 8900 8592 8594 9053 9109 9054 9059f
,"#"
"####"
"#########"
"############"
"######"
"#########################"
""
""
"###########"
,"#"

说明:

大多数代码用于创建bin将输入存储到的存储桶。

{sum[t=/:bin[m+.1*(t:til 10)*max[x]-m:min x;x]]#'"#"} / ungolfed solution
{                                                   } / lambda function with implicit x as parameter
                                               #'"#"  / take (#) each-both "#", 1 2 3#'"#" => "#","##","###"
 sum[                                         ]       / sum up everything inside the brackets
         bin[                              ;x]        / binary search each x in list (first parameter)
                                    m:min x           / store minimum of list x in variable m
                             max[x]-                  / subtract from the maximum of list x
                  (t:til 10)*                         / range 0..9 vectorised multiplication against max delta of list
               .1*                                    / multiply by 0.1 (aka divide by 10)
             m+                                       / minimum of list vectorised addition against list
     t=/:                                             / match each-right against range 0..9 (buckets)

0

果冻,19字节

_Ṃµ÷Ṁ×⁵Ḟ«9ċЀ⁵Ḷ¤”#ẋ

在线尝试!

这是基于我对原始问题的APL回答,我将在比赛结束后发布该问题。

怎么样?(我不擅长解释事情)

_Ṃµ÷Ṁ×⁵Ḟ«9ċЀ⁵Ḷ¤”#ẋ
_Ṃ                  = subtract the minimum
  µ                 = Sort of like a reverse-order compose
   ÷Ṁ               = divide by the max
     ×⁵             = Multiply by 10
       Ḟ            = Take the floor
        «9          = x => min(x,9)
          ċЀ⁵Ḷ¤    = count occurrences of [0,...,9]
                ”#ẋ = create the list
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.