Alphanumerisches Gleichgewicht


15

Schreiben Sie ein Programm, das eine Zeichenfolge als Eingabe erhält und die Anzahl der darin enthaltenen alphanumerischen und nicht-alphanumerischen Zeichen zählt. Es muss sein Ergebnis so anzeigen:

Eingabe: http://stackexchange.com
Ausgabe:20 + 4 = 24

Der Haken ist, dass Ihr Quellcode die gleiche Anzahl von alphanumerischen Zeichen haben muss wie nicht-alphanumerische. Kommentare sind nicht erlaubt, Leerzeichen werden ignoriert. (Die Sprache mit dem Namen Whitespace kann um Stimmen konkurrieren, wird aber offensichtlich nicht als Gewinner ausgewählt.)

Zeichen im Code müssen mindestens eine geringfügige Rechtfertigung haben, sie sollten nicht völlig überflüssig sein. Beispielsweise sind längere Variablennamen i = (j*3)+4;anstelle von i = j*3+4;zulässig. Ist i = i + 1;;;;;;es aber nicht.

Außerdem gelten die Standardregeln für Code-Golf.


Wenn ich definieren eine neue, vorverarbeitet Variante Ook , wo die Schlüsselwörter sind O., O?und O!dann irgendein Programm , das ich schreiben erfüllt die Zeichenklasse Einschränkung ... Natürlich ist es wahrscheinlich auf die Länge Geschäft zu verlieren.
DMCKEE

2
wird alles ascii sein?
Jordon Biondo

@JordonBiondo: Ich habe an alles gedacht, was Sie wollen, vom vollständigen 8-Bit-ANSI bis zum Unicode, aber wenn Ihr Code nur 7-Bit-ASCII unterstützt, werde ich das auch akzeptieren.
vsz

3
Wird das Leerzeichen in der Ausgabezeichenfolge in die nicht-alphanumerische Zeichenfolge gezählt? Oder ignoriert mit all den anderen (non-string-literal) Leerzeichen?
Kninnug

1
@dmckee: Wenn Sie Ihre eigene Sprache definieren möchten, definieren Sie einfach eine Variante der Sprache Ihrer Wahl, in der nicht leere Programme genau wie in der Basissprache funktionieren, das leere Programm jedoch in Code vorverarbeitet wird, der genau das tut, was das tut frage fragt nach.
user2357112 unterstützt Monica

Antworten:


8

Perl, 32 + 32 = 64

Die Zeichenfolge wird in STDIN erwartet. Die Ausgabe wird nach STDOUT geschrieben. Leerzeichen werden ignoriert. Meine Interpretation der Aufgabe ist, dass das Programm in der Lage sein sollte, auf sich selbst zu laufen, um die Punktzahl zu erhalten.

$/ = $,;
$_ = <>;
s x\sxxg;
$\ = length;
print s x[0-9a-z]xxgi,
      ' + ',
      s x.xxg,
      ' = '

Ungolfed mit Kommentaren

$/ = $,; # The input separator becomes undefined, because the default for $, is "undef"
$_ = <>; # now $_ takes the whole file (STDIN) instead of the first line
s x\sxxg; # $_ =~ s/\s//g;
          # white space is removed from $_
$\ = length; # The number of the other characters are put into $\,
             # which is automatically printed the end of "print".
print s x[0-9a-z]xxgi, # s/[0-9a-z]//gi
                       # Remove alphanumeric characters and return their count
      ' + ',
      s x.xxg, # s/.//g
               # Remove the remaining special characters and return their count.
               # "." does not catch new lines, but we have already
               # removed white spaces including new lines.
      ' = '

Ich habe mehrere Variationen mit der gleichen Anzahl von Bytes gefunden, zB:

$/ = $x;
$_ = <>, s x\sxxg;
$\ = split $x;
print s x[\da-z]xxgi,
      " + ",
      s x.xxg,
      ' = '

Beispiele

  • Beispiel aus der Frage:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Laufen auf sich selbst ( a.pl):

    cat a.pl | perl a.pl
    32 + 32 = 64

    Die Dateigröße beträgt 104 Bytes, daher werden 40 Bytes als Leerzeichen ignoriert.

Perl, 29 + 29 = 58

$_=<>;s x\sxxg;$\=length;print s x[0-9a-z]xxgi,' + ',s/.//g,' = '

Der String wird bei STDIN erwartet und ist auf die erste Zeile beschränkt. Das Ergebnis wird nach STDOUT gedruckt. Leerzeichen werden ignoriert.

Ungolfed

$_ = <>;
s x\sxxg; # same as s/\s//gx; removes white space;
$\ = length($_); # sum is automatically appended at the end of print
print sx[0-9a-z]xxgi, # same as s/[0-9a-z]//gi;
                      # the number of alphanumeric characters
      ' + ',
      s/.//g, # the number of the remaining special characters
      ' = '

Beispiele

Datei a.plenthält das Perl-Skript.

  • Beispiel aus der Frage:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Laufen auf sich selbst:

    cat a.pl | perl a.pl
    29 + 29 = 58

    Die Dateigröße a.plbeträgt 65 Bytes, daher werden 7 Bytes als Leerzeichen ignoriert.


Anscheinend nehmen Sie an, dass sich die Eingabe nur in einer Zeile befindet ... Ich habe nichts davon in der Spezifikation gesehen? Was ist auch die Begründung für das / x-Flag in der ersten Ersetzung?
Skibrianski

@skibrianski: (a) Die Frage nach der Spezifikation von "string" ist nicht eindeutig. Jetzt habe ich eine Variante hinzugefügt, die ganze Dateien lesen kann. (b) Auch ist mir nicht klar, wie Leerzeichen vom Skript behandelt werden sollen. Meine Interpretation ist, dass Leerzeichen sowohl in der Aufgabe als auch in der Partitur ignoriert werden. (c) Das / x-Flag ermöglicht Leerzeichen im Muster, um die Lesbarkeit zu verbessern. Die aktualisierte Antwort macht davon Gebrauch.
Heiko Oberdiek

Zu a), der Autor sagt nichts darüber, was in der Zeichenkette enthalten sein wird, also würde ich vermuten, dass es unklug ist, Annahmen zu treffen, was für mich bedeutet, dass Zeilenumbrüche erlaubt sein müssen. Zu b) vereinbart, ist es nicht klar. Zu c) Richtig, aber in Ihrer Antwort fügt das Leerzeichen meinem Auge keine Lesbarkeit hinzu, sondern lediglich ein alphanumerisches Zeichen in einer deiner regulären Ausdrücke, vermutlich, um das letzte zusätzliche alphanumerische Zeichen hinzuzufügen, damit die Zählungen übereinstimmen =) Trotzdem mag ich deine Antwort. Ich habe mir etwas Ähnliches ausgedacht.
Skibrianski

haha jetzt haben wir im Wesentlichen identischen Code =) gute Show =)
Skibrianski

@skibrianski: :-) Danke, du gibst mir einen Grund, eine der anderen Varianten mit etwas mehr Unterschieden zu posten. Die Anzahl der Bytes bleibt jedoch erhalten.
Heiko Oberdiek

6

C - 96 (48 + 48) Zeichen

Es ist etwas lesbar. Es gibt jedoch Raum für Verbesserungen.

i,j;main(_){while((_=getchar())>=0)isspace(_)||(isalnum(_)?i++:j++);printf("%i + %i = %i",i,j
,i+j);}

5

Bash + Coreutils, 72 (36 + 36) Zeichen ohne Leerzeichen

a=`tr -dc [:alnum:]<<<$1|wc -c`
n=`tr -dt [:space:]<<<$1|wc -c`
echo $a + $[n-a] = $n

Ausgabe:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (cat alnumbalance.sh)"
36 + 36 = 72
$ 

Vorherige Antwort:

Pure Bash, 92 (46 + 46) Zeichen ohne Leerzeichen

nosp=${1//[[:space:]]}
noaln=${nosp//[[:alnum:]]}
echo $[${#nosp}-${#noaln}] + ${#noaln} = ${#nosp}

Ausgabe:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (cat alnumbalance.sh)"
46 + 46 = 92
$ 

Woohoo - es schlägt sogar Golfscript ! ;-)
Digital Trauma

Was ist mit Steuerzeichen? [: alnum:] ist nicht das Gegenteil von [: punct:]. Versuchen Sie zB head -c256 / dev / urandom | tr -d [: alnum:] [: punct:]
skibrianski

@ Skibrianski guter Punkt. Ich habe die Antwort bearbeitet, um dies zu berücksichtigen.
Digital Trauma

3

PowerShell (43 + 43 = 86)

Golf gespielt

function alf($i){$a=0;$n=0;[char[]]$i|%{if($_-match"[a-zA-Z0-9]"){$a++}else{$n++}}; write-host "$a+$n=$($a+$n)"}

Nicht golfen

function alf($i){
    $a=0;$n=0;  
    [char[]] $i | %{ if ($_ -match "[a-zA-Z0-9]") { $a++ } else { $n++ } };
    write-host "$a+$n=$($a + $n)"
}

Prüfung

PS > alf "http://stackexchange.com"
20+4=24

Testen mit dem Code selbst, um die Kriterien zu erfüllen

PS > alf "function alf($i){$a=0;$n=0;[char[]]$i|%{if($_-match`"[a-zA-Z0-9]`"){$a++}else{$n++}}; write-host `"$a+$n=$($a+$n)`"}"
43+43=86

" wurde mit `maskiert, was nicht Teil der Zeichenkette ist.


2

GolfScript, 74 Zeichen (= 37 + 37)

{+}:PLUS;.,.@10,''*26,{65PLUS.32|}%PLUS$-,\1$-' + 'PLUS\PLUS' = 'PLUS\PLUS

Online-Test für den Code mit dem Code als Eingabe.


2

Rubin 38 + 38 = 76

Dieses Programm zählt nachgestellte Zeilenumbrüche in der Eingabe.

puts"#{a=gets.scan(/[a-z0-9]/i).length}+#{b=$_.scan(/\W|_/).length}=#{a+b}"

Die Zeichenanzahl wird vom Programm selbst festgelegt: $ ruby alphabalance.rb alphabalance.rb:)


2

PowerShell, 70 Byte (= 35 + 35)

param($s)"$(($l=$s.Length)-($n=($s|sls '\W' -a).Matches.Count))+$n=$l"

Testskript:

$f = {
param($s)"$(($l=$s.Length)-($n=($s|sls '\W' -a).Matches.Count))+$n=$l"
}

&$f "http://stackexchange.com"
&$f $f.toString().Trim()

Ausgabe:

20+4=24
35+35=70

PowerShell, 70 Byte (= 35 + 35), alternativ

"$(($l="$args"|% Length)-($n=($args|sls '\W'-a).Matches.Count))+$n=$l"

2

Python 2 (60 + 60 = 120)

Schwierig, es gibt wahrscheinlich Raum für Verbesserungen. Wie die Tatsache, dass die Funktion selbst verwendet werden kann, um eine eigene alphanumerische Waage auszuwerten.

def f(s):
 i=j=0
 for c in s:
  t=ord(c)
  if (t!=2**5): 
   i+=1  
  if (48<=t<=57 or 65<=t<=90 or 97<=t<=122):
   j+=1 
 print `j`,'+',`i-j`,'=',i      

Prüfung:

>>> f("http://stackexchange.com")
20 + 4 = 24

Welche Version von Python ist das?
Gigaflop

@Gigaflop Ich habe es bearbeitet. Die print-Anweisung ist nur Python 2, ebenso wie die Backtick-Syntax für repr.
mbomb007

1

C ++, 146 (73 + 73) 178 (89 + 89) Nicht-Leerzeichen #

Original <algorithm>ohne guten Grund enthalten. Hoppla.

//create a test string
#include<string>
std::string a = "\?\?=include <cstdio>\
int x,y;\
int main()\?\?<\
    for(char c : a)\
            !isspace(c) ? (isalnum(c) ? y++ : x++) : 0;\
    printf(\"%d\?\?/t%c\?\?/t%d\?\?/t%c\?\?/t%d\?\?/n\",y,'+',x,'=',(x+y));\
\?\?>";

//Code itself starts here
??=include <cstdio>
int x,y;
int main()??<
    for(char c : a)
        !isspace(c) ? (isalnum(c) ? y++ : x++) : 0;
    printf("%d??/t%c??/t%d??/t%c??/t%d??/n",y,'+',x,'=',(x+y));
??>

Ich zähle nur die Zeichen in den folgenden Zeilen //Code itself starts here. Dies bedeutet insbesondere, dass nicht gezählt wird #include <string>. Ich zähle auch Trigraphen als jeweils drei Zeichen, was vielleicht umstritten ist. Beachten Sie, dass beim Testen des Programms im eigenen Quellcode einige Sorgfalt erforderlich ist, um das Ersetzen von Trigraphen innerhalb des String-Literal zu verhindern.

Hier gibt es einige besondere Designentscheidungen - in den meisten Produktionscodes werden Sie nicht auf Trigraphen und bereichsbezogene For-Schleifen in derselben Funktion stoßen -, aber ich halte alles für 'vertretbar'.


1

Python 52 + 52 = 104

Interessante Herausforderung, da Python nicht-alphanumerische Zeichen vermeidet.

def f(_):
    _=_.replace(" ","");l=len(_);a=sum([c.isalnum() for c in _][:l]);print("{0} + {1} = {2}".format(a,l-a,l))

Kleine Rechtfertigung für die Verwendung von Slice: Es beschleunigt es (vielleicht?)


Versuchen Sie es mit Python 2, da printkeine Klammern erforderlich sind, und verwenden Sie die '%d + %d = %d' % (a,l-a,l)Methode. Das sollte einige Zeichen speichern.
mbomb007

1

Julia, 64

f(s)=(b=endof(s);a=sum([isalnum(c) for c in s]);"$(a) + $(b-a) = $(b)";)

Alle unnötigen nicht-alphanumerischen Zeichen sind die letzten ;und einige der ()in der Zeichenfolge enthaltenen Formatierungen. Sie wurden fast perfekt ausbalanciert und als Zweierpotenz ohne viel Fummelei ausgegeben.

julia> f("http://stackexchange.com")
"20 + 4 = 24"
julia> nowhite(s)=join(split("s"," "))
julia> f(nowhite("f(s)=(b=endof(s);a=sum([isalnum(c) for c in s]);\"\$(a)+\$(b-a)=\$(b)\";)"))
"32 + 32 = 64"

1

Perl, 64 Zeichen ohne Leerzeichen:

$/=$,;
$_=<>;
s 0\s00g;
$\=length;
print s 1[a-z0-9]11ig .
      " + " .
      s 2.22g .
      " = "

Leicht über perl -MO = Deparse und einige Kommentare geklärt:

$/ = $,;               # input record separator = a variable defaulting to undef
$_ = <ARGV>;           # slurp stdin
s/\s//g;               # strip whitespace
$\ = length $_;        # output record separator = total length of string sans whitespace
print s/[a-z0-9]//gi . ' + ' . s/.//g . ' = '; # count alphanumerics, then everything else

Das ORS $ \ wird bei jedem Druckaufruf automatisch angehängt, wobei die Gesamtzahl am Ende steht.


Hatte 66 Zeichen bei meinem ersten Durchgang. Vielen Dank an Heiko Oberdiek für den Hinweis, dass Sie $ / mit weniger Zeichen
aufheben können,

1

Python 2, 50 + 50 = 100

import re
def f(i):
    w = re.sub('\s', '', i)
    s = re.subn('[\W_]', '', w)
    a = len(s[0])
    print '%d + %d = %d' % (a, s[1], a+s[1])

Führen Sie es hier aus: http://repl.it/8CH


0

Rebol (64 + 64 = 128)

f: func [x] [
    c: :charset
    a: c [#"a" - #"z"]
    s: c [#" " #"^/" #"^-"]
    n: complement union a s
    a+: n+: 0
    parse x [
        some [
            a (++ a+) |
            n (++ n+) |
            s
        ]
    ]
    print [a+ "+" n+ "=" a+ + n+]
]

Anwendungsbeispiel (in der Rebol-Konsole):

>> f "http://stackexchange.com"
20 + 4 = 24

NB. Das Programm ignoriert Leerzeichen, Tabulatoren und Zeilenumbrüche.


0

J - 46 + 46 = 92

Zählt Whitespace, sodass Sie ohne Änderung keinen Selbsttest durchführen können. Übernimmt die Eingabe für stdin. Hat einen schlechten Mund, sollte es mit Seife auswaschen gehen.

;":&.>(+/;' + ';(#-+/);' = ';#)(e.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10

Verwendung:

   ;":&.>(+/;' + ';(#-+/);' = ';#)(e.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10
http://stackexchange.com
20 + 4 = 24

   NB. modification for self-test:    vvvvvv - remove spaces, the only whitespace
   ;":&.>(+/;' + ';(#-+/);' = ';#)(e.~' '-.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10
;":&.>(+/;' + ';(#-+/);' = ';#)(e.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10
46 + 46 = 92

0

Javascript - 76 (38 + 38)

_ = prompt()
o = _.match(/[a-z0-9]/gi).length
$ = _.length - o
alert(o + " + " + $ + " = " + (o + $))

Beispiel Input: http://stackexchange.com
Output:20 + 4 = 24

Laufen auf sich selbst:

var a  = '_ = prompt()o = _.match(/[a-z0-9]/gi).length$ = _.length - oalert(o + " + " + $ + " = " + (o + $))'

var letters = a.match(/[a-z0-9]/g).length; 
var nons = a.match(/[^a-z0-9 ]/g).length; // excludes whitespace from count

console.log(nons + " = " + letters); // 38 = 38 :)

PS Für diejenigen, die daran interessiert (o + $)sind, ein alphanumerisches Gleichgewicht aufrechtzuerhalten, ist dies nicht der Fall. Denn nach dem Sehen von o + " + "JS würden sich alle dafür entscheiden +, String-Konkatenatoren statt Zahlenaddierer zu sein. Somit sind die Klammern notwendig oder 20 + 4würden 204eher werden als 24: D

Viel Spaß beim Codieren!


0

Clojure: (31 + 31 = 62) Zeichen ohne Leerzeichen

(def ff #(let [c count y (c %) x (c (re-seq #"\w" %))] (str x " + " (- y x) " = " y)))

Ausgabe:

alphabalance.core=> (ff "http://stackexchange.com")
"20 + 4 = 24"

0

CJam, 27 + 27 = 54

CJam ist ein paar Monate neuer als diese Herausforderung, daher ist diese Antwort nicht für das grüne Häkchen geeignet. Es war trotzdem eine lustige Übung!

ea0=eu{A,s'[,65>+#)g}%_:+1@f-:+ea0=,]"DODDaD"36f-3/]zo

Die Eingabezeichenfolge wird als Befehlszeilenargument verwendet, sodass sie im Online-Interpreter nicht funktioniert. Sie können sie jedoch mit dem Befehl testen Java-Interpreter .

Erläuterung

"Distinguish alphanumeric characters:";
ea0=eu{A,s'[,65>+#)g}%
ea0=                   "Get the first command-line argument.";
    eu                 "Convert it to upper case.";
      {             }% "Map this block onto each character.";
       A,s             "Get the string '0123456789'.";
          '[,          "Get a string with all characters from the null byte to Z.";
             65>       "Remove the first 65 characters, to leave A to Z.";
                +      "Add to digit.";
                 #     "Find character in that string. Returns -1 if not alphanumeric.":
                  )g   "Increment and get signum. Yields 1 for alphanumeric characters,
                        0 otherwise.";

"Now we've got an array of 0s and 1s. Let's do the counting:";
_:+1@f-:+ea0=,]
_               "Duplicate array.";
 :+             "Get the sum. This is the number of alphanumeric characters.";
   1@           "Push a 1 and pull up the other copy of the array.";
     f-         "Subtract each element from 1, this swaps 0s and 1s.";
       :+       "Get the sum. This is the number of symbol characters.";
         ea0=   "Get the first command-line argument again.";
             ,  "Get its length. This is the total number of characters.";
              ] "Collect everything in an array.";

"And now the formatting:";
"DODDaD"36f-3/]zo
"DODDaD"          "Push this string.";
        36f-      "Subtract 36 from each character. This yields ' +  = '.";
            3/    "Split into two halves of 3 characters each.";
              ]   "Wrap this and the previous array in another array.";
               z  "Zip. Transposes the array to interleave strings with numbers.";
                o "Output the resulting array without delimiters.";
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.