Entropy/Narcissist: Difference between revisions
→{{header|jq}}: def sum():
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
(→{{header|jq}}: def sum():) |
||
(20 intermediate revisions by 15 users not shown) | |||
Line 1:
{{task}}
[[File:ENTROPY.JPG|
;Task:
Line 10:
:* [[Entropy]]
<br><br>
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_Io;
with Ada.Command_Line;
with Ada.Numerics.Elementary_Functions;
procedure Entropy is
use Ada.Text_Io;
type Hist_Type is array (Character) of Natural;
function Log_2 (V : Float) return Float is
use Ada.Numerics.Elementary_Functions;
begin
return Log (V) / Log (2.0);
end Log_2;
procedure Read_File (Name : String; Hist : out Hist_Type) is
File : File_Type;
Char : Character;
begin
Hist := (others => 0);
Open (File, In_File, Name);
while not End_Of_File (File) loop
Get (File, Char);
Hist (Char) := Hist (Char) + 1;
end loop;
Close (File);
end Read_File;
function Length_Of (Hist : Hist_Type) return Natural is
Sum : Natural := 0;
begin
for V of Hist loop
Sum := Sum + V;
end loop;
return Sum;
end Length_Of;
function Entropy_Of (Hist : Hist_Type) return Float is
Length : constant Float := Float (Length_Of (Hist));
Sum : Float := 0.0;
begin
for V of Hist loop
if V > 0 then
Sum := Sum + Float (V) / Length * Log_2 (Float (V) / Length);
end if;
end loop;
return -Sum;
end Entropy_Of;
package Float_Io is new Ada.Text_Io.Float_Io (Float);
Name : constant String := Ada.Command_Line.Argument (1);
Hist : Hist_Type;
Entr : Float;
begin
Float_Io.Default_Exp := 0;
Float_Io.Default_Aft := 6;
Read_File (Name, Hist);
Entr := Entropy_Of (Hist);
Put ("Entropy of '");
Put (Name);
Put ("' is ");
Float_Io.Put (Entr);
New_Line;
end Entropy;</syntaxhighlight>
{{out}}
<pre>Entropy of 'entropy.adb' is 4.559854</pre>
=={{header|ALGOL 68}}==
Line 16 ⟶ 86:
Note that the source here uses spaces, not tabs, hence the low entropy, replacing all runs of four spaces with a single space
results in an entropy of +4.64524532762062e +0.
<
# calculate the shannon entropy of a string #
PROC shannon entropy = ( STRING s )REAL:
Line 74 ⟶ 144:
print( ( shannon entropy( file contents ), newline ) )
FI
END</
{{out}}
<pre>
Line 82 ⟶ 152:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey 1.1}}
<
MsgBox, % Entropy(var)
Line 97 ⟶ 167:
}
return, e
}</
{{Output}}
<pre>5.942956</pre>
=={{header|AWK}}==
The record separator RS is set to end of file. So getline reads the whole file in one line.
<syntaxhighlight lang="awk">
BEGIN{FS=""
RS="\x04"#EOF
getline<"entropy.awk"
for(i=1;i<=NF;i++)H[$i]++
for(i in H)E-=(h=H[i]/NF)*log(h)
print "bytes ",NF," entropy ",E/log(2)
exit}</syntaxhighlight>
{{Output}}
<pre>bytes 158 entropy 5.2802</pre>
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> DIM Freq%(255)
FOR I%=PAGE TO LOMEM Freq%(?I%)+=1 NEXT
Size=LOMEM - PAGE
FOR I%=0 TO 255
IF Freq%(I%) Entropy+=Freq%(I%) / Size * LN(Freq%(I%) / Size) / LN(2)
NEXT
PRINT "My size is ";Size " bytes and my entropy is ";-Entropy "!"
END</syntaxhighlight>
{{out}}
<pre>My size is 224 bytes and my entropy is 5.11257089!</pre>
=={{header|C}}==
Line 106 ⟶ 202:
Assumes that the source file is stored in the working directory as "entropy.c".
<
#include <stdlib.h>
#include <stdbool.h>
Line 153 ⟶ 249:
printf("%lf\n",H);
return 0;
}</
{{out}}
<syntaxhighlight lang="text">5.195143</syntaxhighlight>
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
string readFile (string path) {
string contents;
string line;
ifstream inFile(path);
while (getline (inFile, line)) {
contents.append(line);
contents.append("\n");
}
inFile.close();
return contents;
}
double entropy (string X) {
const int MAXCHAR = 127;
int N = X.length();
int count[MAXCHAR];
double count_i;
char ch;
double sum = 0.0;
for (int i = 0; i < MAXCHAR; i++) count[i] = 0;
for (int pos = 0; pos < N; pos++) {
ch = X[pos];
count[(int)ch]++;
}
for (int n_i = 0; n_i < MAXCHAR; n_i++) {
count_i = count[n_i];
if (count_i > 0) sum -= count_i / N * log2(count_i / N);
}
return sum;
}
int main () {
cout<<entropy(readFile("entropy.cpp"));
return 0;
}</syntaxhighlight>
{{out}}
<
=={{header|Crystal}}==
{{trans|Ruby}}
<
counts = s.chars.each_with_object(Hash(Char, Float64).new(0.0)) { |c, h| h[c] += 1 }
counts.values.sum do |count|
Line 167 ⟶ 308:
end
puts entropy File.read(__FILE__)</
{{out}}
<pre>
Line 174 ⟶ 315:
=={{header|D}}==
<
import std.stdio, std.algorithm, std.math, std.file;
Line 184 ⟶ 325:
.sum
.writeln;
}</
{{out}}
<pre>6.29803</pre>
=={{header|Elixir}}==
<
text = IO.read(file, :all)
leng = String.length(text)
Line 200 ⟶ 341:
end)
|> IO.puts
end)</
{{out}}
Line 208 ⟶ 349:
=={{header|Emacs Lisp}}==
<
(let ((freq-table (make-hash-table))
(entropy 0)
Line 227 ⟶ 368:
(shannon-entropy (with-temp-buffer
(insert-file-contents "U:/rosetta/narcissist.el")
(buffer-string))))</
{{out}}
<
4.5129548515535785</
=={{header|Erlang}}==
<
-define(LOG2E, 1.44269504088896340735992).
Line 257 ⟶ 398:
_ -> count(Data, I+1, Frq #{Chr => 1})
end.
</syntaxhighlight>
{{out}}
<pre>
Line 264 ⟶ 405:
=={{header|Factor}}==
<
math.functions math.statistics prettyprint sequences ;
IN: rosetta-code.entropy-narcissist
Line 275 ⟶ 416:
"entropy-narcissist.factor" utf8 [
contents entropy .
] with-file-reader</
{{out}}
<pre>
Line 282 ⟶ 423:
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
' modified code from ENTROPY entry
Line 334 ⟶ 475:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre>Windows version
Line 347 ⟶ 488:
=={{header|Go}}==
<
import (
Line 381 ⟶ 522:
l := float64(len(d))
return math.Log2(l) - hm/l
}</
{{out}}
<pre>
Line 389 ⟶ 530:
=={{header|Haskell}}==
<
import Data.List
import System.Environment
Line 399 ⟶ 540:
entropy = sort >>> group >>> map genericLength >>> normalize >>> map lg >>> sum
where lg c = -c * logBase 2 c
normalize c = let sc = sum c in map (/ sc) c</
{{out}} In a shell
Line 416 ⟶ 557:
=={{header|J}}==
'''Solution''':<
1!:2&2 entropy 1!:1 (4!:4 <'entropy') { 4!:3''</
'''Example''':<
4.73307</
=={{header|Java}}==
<
import java.io.BufferedReader;
import java.io.File;
Line 464 ⟶ 605:
}
</syntaxhighlight>
{{out}}
<pre>Entropy of file "src/EntropyNarcissist.java" = 4.691381977073.</pre>
=={{header|jq}}==
'''Works with jq, the C implementation of jq'''
'''Works with gojq, the Go implementation of jq'''
'''Works with jaq, the Rust implementation of jq'''
The program assumes it will be presented to itself using
an invocation of jq with the -sR options, along the lines of:
<pre>
jq -sR -f entropy-narcissist.jq < entropy-narcissist.jq
</pre>
If your jq supports `keys_unsorted`, feel free to use it instead of `keys`.
<syntaxhighlight lang="jq">
def chars: explode[] | [.] | implode;
def bow(stream):
reduce stream as $word ({}; .[($word|tostring)] += 1);
def sum(s): reduce s as $x (0; .+$x);
length as $l
| bow(chars)
| sum(keys[] as $k | .[$k] as $c | $c * ($c|log2) )
| ($l|log2) - ./$l
</syntaxhighlight>
{{output}}
<pre>
{{output}}
<pre>
4.796499915496963
</pre>
=={{header|Julia}}==
<
entropy(s) = -sum(x -> x / length(s) * log2(x / length(s)), values(counter(s)))
println("self-entropy: ", entropy(read(Base.source_path(), String)))</
{{out}}
Line 479 ⟶ 654:
=={{header|Kotlin}}==
<
fun log2(d: Double) = Math.log(d) / Math.log(2.0)
Line 501 ⟶ 676:
val prog = java.io.File("entropy_narc.kt").readText()
println("This program's entropy is ${"%18.16f".format(shannon(prog))}")
}</
{{out}}
Line 510 ⟶ 685:
=={{header|Lua}}==
arg[0] gives the path of the script currently being executed
<
local inFile = io.open(filename, "r")
local fileContent = inFile:read("*all")
Line 535 ⟶ 710:
end
print(entropy(getFile(arg[0])))</
{{out}}
<pre>4.3591214356783</pre>
=={{header|Nim}}==
As we have compiled without specific options to change the way the executable is named, we can retrieve the source file name by adding the suffix “.nim” to the executable file name. We suppose also that the source file is in the same directory as the executable (which is true in our environment).
<syntaxhighlight lang="nim">import os, math, strutils, tables
let execName = getAppFilename().splitPath().tail
let srcName = execName & ".nim"
func entropy(str: string): float =
var counts: CountTable[char]
for ch in str:
counts.inc(ch)
for count in counts.values:
result -= count / str.len * log2(count / str.len)
echo "Source file entropy: ", srcName.readFile().entropy().formatFloat(ffDecimal, 5)
echo "Binary file entropy: ", execName.readFile().entropy().formatFloat(ffDecimal, 5)</syntaxhighlight>
{{out}}
<pre>Source file entropy: 4.75555
Binary file entropy: 5.97036</pre>
=={{header|PARI/GP}}==
<
entropy(Str(entropy))</
{{out}}
<pre>%1 = 4.54978213</pre>
=={{header|Perl}}==
<
use strict ;
use warnings ;
Line 572 ⟶ 769:
}
$infocontent *= -1 ;
say "The information content of the source file is $infocontent !" ;</
{{out}}
<pre>The information content of the source file is 4.6487923749222 !</pre>
Line 578 ⟶ 775:
=={{header|Phix}}==
Minor edit to the [[Entropy#Phix|Entropy]] answer, if compiled assumes source code is in the same directory.
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- command_line, file i/o</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">entropy</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">symbols</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">counts</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">N</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">N</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">,</span><span style="color: #000000;">symbols</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">symbols</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">symbols</span><span style="color: #0000FF;">,</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">counts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span
<span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">H</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">counts</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">ci</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]/</span><span style="color: #000000;">N</span>
<span style="color: #000000;">H</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">ci</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">log2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">H</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">entropy</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">command_line</span><span style="color: #0000FF;">()[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #008000;">".exe"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">".exw"</span><span style="color: #0000FF;">)),</span><span style="color: #008000;">"rb"</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
Output is eg 4.993666233, but that may vary with Windows/Linux line endings, tabs vs spaces, trailing returns, BOM headers, etc.
=={{header|PHP}}==
<
$h = 0;
$s = file_get_contents(__FILE__);
Line 621 ⟶ 813:
( $c / $l ) *
log( $c / $l, 2 );
echo $h;</
{{out}}
<pre>2.9339128173013</pre>
=={{header|Picat}}==
{{trans|Go}}
{{works with|Picat}}
<syntaxhighlight lang="picat">
entropy(File) = E =>
Bytes = read_file_bytes(File),
F = [0: I in 1..256],
foreach (B in Bytes)
B1 := B + 1,
F[B1] := F[B1] + 1
end,
HM = 0,
foreach (C in F)
if (C > 0) then
HM := HM + C * log(2, C)
end
end,
L = Bytes.length,
E = log(2, L) - HM / L.
main(Args) =>
printf("Entropy: %f\n", entropy(Args[1])).
</syntaxhighlight>
{{out}}
<pre>
$ picat entropy.pi entropy.pi
Entropy: 4.384622
</pre>
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">
(scl 8)
(load "@lib/math.l")
(setq LN2 0.693147180559945309417)
(setq Me
(let F (file)
(pack (car F) (cadr F))))
(setq Hist NIL Sz 0)
(in Me
(use Ch
(while (setq Ch (rd 1))
(inc 'Sz)
(if (assoc Ch Hist)
(con @ (inc (cdr @)))
(setq Hist (cons (cons Ch 1) Hist))))))
(prinl "My entropy is "
(format
(*/
(sum
'((Pair)
(let R (*/ (cdr Pair) 1. Sz)
(- (*/ R (log R) 1.))))
Hist)
1. LN2)
*Scl))
(bye)
</syntaxhighlight>
{{Out}}
<pre>
My entropy is 4.12169822
</pre>
=={{header|Python}}==
Line 631 ⟶ 890:
Minor edit to the [[Entropy#Python|Entropy]] answer.
<
from collections import Counter
Line 641 ⟶ 900:
b=f.read()
print(entropy(b))</
{{Output}}
<pre>4.575438063744619</pre>
Line 647 ⟶ 906:
=={{header|Racket}}==
The entropy of the program below is 4.512678555350348.
<
#lang racket
(require math)
Line 655 ⟶ 914:
(- (for/sum ([(d c) (in-hash (samples->hash ds))])
(* (/ c n) (log2 (/ c n)))))
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2016.05}}
<syntaxhighlight lang="raku"
given slurp($*PROGRAM-NAME).comb</
Result should be in the neighborhood of 4.9
{{out}}
Line 668 ⟶ 927:
=={{header|REXX}}==
REXX doesn't have a BIF (built-in function) for '''log''' or '''ln''', so the subroutine (function) '''log2''' is included herein.
<
numeric digits length( e() ) % 2 - length(.) /*use 1/2 of the decimal digits of E. */
#= 0; @.= 0; $=; $$=; recs= sourceline() /*define some handy─dandy REXX vars. */
Line 698 ⟶ 957:
ox=izz; ii=ii+is*2**j; end /*while*/; x= x * e** -ii -1; z= 0; _= -1; p= z
do k=1; _= -_ * x; z= z+_/k; if z=p then leave; p= z; end /*k*/
r= z + ii; if arg()==2 then return r; return r / log2(2,.)</
{{out|output|text= when using this REXX program as input:}}
<pre>
Line 709 ⟶ 968:
=={{header|Ruby}}==
<
counts = s.each_char.
size = s.size.to_f
counts.values.reduce(0) do |entropy, count|
freq = count /
entropy - freq * Math.log2(freq)
end
end
s = File.read(__FILE__)
p entropy(s)
</syntaxhighlight>
{{out}}
<pre>4.653607496799478
</pre>
=={{header|Rust}}==
<
use std::io::{Read, BufReader};
Line 750 ⟶ 1,010:
let file = BufReader::new(File::open(name).expect("Could not read file."));
println!("Entropy is {}.", entropy(file.bytes().flatten()));
}</
{{out}}
<pre>Entropy is 5.7108583.</pre>
=={{header|Sidef}}==
<
[0,
s.chars.freq.values.map {|c|
Line 764 ⟶ 1,024:
}
say entropy(File(__FILE__).open_r.slurp)</
{{out}}
<pre>
Line 772 ⟶ 1,032:
=={{header|Tcl}}==
Note that this code doesn't bother to close the open handle on the script; it is only suitable as a demonstration program.
<
set log2 [expr log(2)]
foreach char [split $str ""] {dict incr counts $char}
Line 783 ⟶ 1,043:
}
puts [format "entropy = %.5f" [entropy [read [open [info script]]]]]</
{{out}}
<pre>
entropy = 4.59099
</pre>
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="go">import os
import math
fn main() {
println("Binary file entropy: ${entropy(os.args[0])?}")
}
fn entropy(file string) ?f64 {
d := os.read_bytes(file)?
mut f := [256]f64{}
for b in d {
f[b]++
}
mut hm := 0.0
for c in f {
if c > 0 {
hm += c * math.log2(c)
}
}
l := f64(d.len)
return math.log2(l) - hm/l
}</syntaxhighlight>
{{out}}
<pre>
Binary file entropy: 5.676177202237735
</pre>
=={{header|Wren}}==
Basically an amalgam of the code in the [[Print_itself#Wren]] and [[Entropy#Wren]] tasks.
<syntaxhighlight lang="wren">import "os" for Process
import "io" for File
var args = Process.allArguments
var s = File.read(args[1]).trim()
var m = {}
for (c in s) {
var d = m[c]
m[c] = (d) ? d + 1 : 1
}
var hm = 0
for (k in m.keys) {
var c = m[k]
hm = hm + c * c.log2
}
var l = s.count
System.print(l.log2 - hm/l)</syntaxhighlight>
{{out}}
<pre>
4.6302314663
</pre>
=={{header|XPL0}}==
To run: entropy < entropy.xpl
<syntaxhighlight lang "XPL0">int Count(128), I, Len, Ch;
real Sum, Prob;
[for I:= 0 to 127 do Count(I):= 0;
Len:= 0;
loop [Ch:= ChIn(1);
if Ch = $1A\EOF\ then quit;
Count(Ch):= Count(Ch)+1;
Len:= Len+1;
];
Sum:= 0.;
for I:= 0 to 127 do
if Count(I) then
[Prob:= float(Count(I)) / float(Len);
Sum:= Sum + Prob*Ln(Prob);
];
RlOut(0, -Sum/Ln(2.));
]</syntaxhighlight>
{{out}}
<pre>
4.63457</pre>
=={{header|zkl}}==
Minor edit to the [[Entropy#zkl|Entropy]] answer.
<
text.pump(Void,fcn(c,freq){ c=c.toAsc(); freq[c]=freq[c]+1; freq }
.fp1((0).pump(256,List,(0.0).create.fp(0)).copy()))
Line 800 ⟶ 1,138:
}
entropy(File("entropy.zkl").read().text).println();</
{{out}}
<pre>
|