15
\$\begingroup\$

This challenge is a cut'n paste from Enlarge ASCII art, but reversed, using PetSCII based half-block chars:

string=" ▝▘▀▗▐▚▜▖▞▌▛▄▟▙█"

There, PetSCII is emulated by using UTF-8 characters, you may found between U+2580 UPPER HALF BLOCK and U+259F QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT.

So the goal is to reduce by 1/2 submited .

You have to group 2 char from 2 lines to obtain one 2x2 pattern for one character:

|XX|         |X |         |X |         |  |
|XX| -> '█'  |XX| -> '▙'  | X| -> '▚'  | X| -> '▗'  and so on...

Some samples: From

 OOOOOO  OOOOOO  OOOOOO  OOOOOOO      OOOOOO   OOOOOO  OO      OOOOOOO 
OO      OO    OO OO   OO OO          OO       OO    OO OO      OO      
OO      OO    OO OO   OO OOOOO       OO   OOO OO    OO OO      OOOOO   
OO      OO    OO OO   OO OO          OO    OO OO    OO OO      OO      
 OOOOOO  OOOOOO  OOOOOO  OOOOOOO      OOOOOO   OOOOOO  OOOOOOO OO      

you have to render:

▟▀▀▘▟▀▀▙▐▛▀▙▐▛▀▀  ▗▛▀▀ ▟▀▀▙▐▌  ▐▛▀▀ 
█   █  █▐▌ █▐▛▀   ▐▌ ▜▌█  █▐▌  ▐▛▀  
▝▀▀▘▝▀▀▘▝▀▀▘▝▀▀▀   ▀▀▀ ▝▀▀▘▝▀▀▀▝▘   

And from:

  OOOOOO  OOOOOO  OOOOOO  OOOOOOO      OOOOOO   OOOOOO  OO      OOOOOOO 
 OO      OO    OO OO   OO OO          OO       OO    OO OO      OO      
 OO      OO    OO OO   OO OOOOO       OO   OOO OO    OO OO      OOOOO   
 OO      OO    OO OO   OO OO          OO    OO OO    OO OO      OO      
  OOOOOO  OOOOOO  OOOOOO  OOOOOOO      OOOOOO   OOOOOO  OOOOOOO OO      

Where 1st column hold spaces you may render:

▗▛▀▀▗▛▀▜▖█▀▜▖█▀▀▘  ▟▀▀▘▗▛▀▜▖█   █▀▀▘ 
▐▌  ▐▌ ▐▌█ ▐▌█▀▘   █ ▝█▐▌ ▐▌█   █▀▘  
 ▀▀▀ ▀▀▀ ▀▀▀ ▀▀▀▘  ▝▀▀▘ ▀▀▀ ▀▀▀▘▀    

Piping:

wget -O - https://codegolf.stackexchange.com/q/19123/9424 |
    sed -ne '/<pre><code>/,/<\/code><\/pre>/{//{/\//q};s/<pre><code>//;p}'
   ('l2v2l6v2'+  'e1l1v3l2'+
 'v3e1v7e1v7e1v7e1l2v6e1l4v5'+
'e1l6v4e1l8v3e1l7l3v2e1l9l3v1')
 .replace(/[lve]\d/g,function
   (c){return Array(-~c[1]).
      join({l:' ',v:'Love'
         ,e:'\n'}[c[0
             ]])})

must give:

▗▟█████▙▟█████▄
▜█████████████▛▘
 ▝▀███▙▛█████▀ 
    ▝▀▜██▀▘

Other samples on my terminal:

asciiReduce sample

With standard rules:

  • Input ASCII from STDIN or file, without special chars, tabulations or UTF-8.
  • Each submited chars have to be represented, only whitespaces have to stay empty.
  • This is too, so the lowest score win. Score is computed as:
    • +1 by chars, to be counted in chars, not in bytes!! Ie: s=' ▝▘▀▗▐▚▜▖▞▌▛▄▟▙█' count for 20 chars, not 52 !!
    • -10 for explanation;
    • +20 for use of external font tool or library.
\$\endgroup\$
  • \$\begingroup\$ So to clarify: the input image is divided into 2x2 squares and each maps onto one character? \$\endgroup\$ – Peter Taylor Jan 29 '14 at 8:25
  • 2
    \$\begingroup\$ -0.5 for adding strange bonuses (define explanation) - after rounding still an upvote. Also this is then code-challenge and not code-golf. \$\endgroup\$ – Howard Jan 29 '14 at 15:49
  • \$\begingroup\$ Most of these chars does not renders correctly in my browser. :( \$\endgroup\$ – Victor Stafusa Jan 30 '14 at 2:08
  • \$\begingroup\$ Under my linux, I use xterm -xrm 'XTerm*renderFont:false' & to open a console window able to display this properly. \$\endgroup\$ – F. Hauri Jan 30 '14 at 10:15
  • \$\begingroup\$ I think you need to specify a) how the reduction is to be done and b)reword your bonuses(and probably remove the one for explanations) \$\endgroup\$ – Razetime Nov 7 '20 at 2:55
4
\$\begingroup\$

GolfScript (90 chars)

n/.,1&[""]*+.{,}%$-1=.1&+{1$,-´' '*+}+%2/{zip 2/{~+0\{32=!1$++}/" ▗▝▐▖▄▞▟▘▚▀▜▌▙▛█"3/=}%n}%

A lot of this goes to handling ragged arrays. Nasty test case:

xx
xxx
xxx
xx
x

contains a 3 different 2x2 grids with only one of the 4 cells containing any character at all.

To make things worse, the zip transposition to chop the columns into pairs gives the same output for ["xx" "xxx"]zip and ["xxx" "xx"]zip. I therefore begin by padding out to ensure that all lines are the same even length, and that there are an even number of lines.

Note that this program assumes that the interpreter will treat " ▗▖▄▝▐▞▟▘▚▌▙▀▜▛█" as a string of length 48, even though as per instructions in the question I'm counting it as 16 chars plus delimiters.

I've tested this to the best of my ability, but I can't find a monospace font which actually renders those characters correctly.

\$\endgroup\$
  • \$\begingroup\$ Your code seem fail on second test, with the heart... But nice! +1 as you'r the 1st! \$\endgroup\$ – F. Hauri Jan 29 '14 at 11:55
  • 1
    \$\begingroup\$ Hmm. I don't tend to use zip on ragged arrays, and I'm quite surprised by what it seems to do on e.g. ["##" "###"]. I'm going to have to rethink my approach. \$\endgroup\$ – Peter Taylor Jan 29 '14 at 12:54
  • \$\begingroup\$ Freemono, Unifont, Code2000, and Fixedsys Excelsior all render these characters correctly. \$\endgroup\$ – primo Jan 29 '14 at 13:26
  • \$\begingroup\$ @primo, Unifont is nowhere near monospaced on those characters. Fixedsys Excelsior isn't quite correct either, but it's close enough. \$\endgroup\$ – Peter Taylor Jan 29 '14 at 15:16
  • \$\begingroup\$ Yes! now you have it! Little remark: there is two empty lines at end of output. This don't break any rule! (Note: scoring is a little changed, you may save 10 points;-) \$\endgroup\$ – F. Hauri Jan 29 '14 at 15:45
3
\$\begingroup\$

C++ (gcc), 257 ... 254 248 - 32 - 10 = 212 chars

#include<bits/stdc++.h>
namespace std{int f(){string a,b;for(int i:{1,3}){getline(cin,a={});b.resize(max(a.size()/2,b.size()));for(int j=a.size();j--;)b[j/2]+=(a[j]>32)<<i-j%2;}for(int i:b)cout.write(" ▝▘▀▗▐▚▜▖▞▌▛▄▟▙█"+i*3,3);cout<<endl;cin&&f();}}

Try it online!

Explained:

#include<bits/stdc++.h> // Evil hack to include all STL headers

namespace std {         // Shorter than using namespace std;

int f() {               // int is one byte shorter than void
  string a, b;          // a will hold one input line, b will hold one reduced line

  for (int i: {1, 3}) {                           // Do two iterations:
    getline(cin, a = {});                         // Read an input line, make sure it is empty first
    b.resize(max(a.size() / 2, b.size()));        // Resize b such that it is max of both inputs divided by 2
    for (int j = a.size(); j--;)                  // Loop over all characters in the input line backwards (order doesn't matter here)
      b[j/2] += (a[j] > 32) << i - j % 2;         // Set the bits in b depending on the presence of non-whitespace in a
  }

  for (int i: b)                                  // For each character in b:
    cout.write("⠀▝▘▀▗▐▚▜▖▞▌▛▄▟▙█" + 3 * i, 3);    // Write the corresponding multibyte character

  cout << endl;                                   // Write a newline and annoy people with an unnecessary flush

  cin && f();                                     // If we didn't reach the end of the input yet:
                                                  // Tail recurse to the start of the function
}

}

Thanks to Razetime for fixing the wrong space character. I also found an issue if the input is an odd number of lines, which required three extra characters to fix. Thanks to ceilingcat for shaving off 9 bytes.

\$\endgroup\$
3
\$\begingroup\$

APL (Dyalog Extended), 38 - 10 = 28 chars

' ▗▖▄▝▐▞▟▘▚▌▙▀▜▛█'[{2⊥∊⍵}⌺(2 2⍴2)≠⎕⍪0]

Try it online!

-10 bytes for an explanation? Count me in!

-14 bytes from Adám.

Takes input as a list of lines from STDIN.

Explanation

' ▗▖▄▝▐▞▟▘▚▌▙▀▜▛█'[{2⊥∊⍵}⌺(2 2⍴2)⊢↑{2|≢⍵:⍵,0⋄⍵}' '≠⎕]
                                                   ⎕  take input
                                               ' '≠   convert spaces to 0, 1 otherwise
                                   {2|≢⍵:⍵,0⋄⍵}       if there are an odd number of rows, append a 0 to each column
                                  ⊢↑                  convert to matrix, apply the following:
                          ⌺(2 2⍴2)                    cut the matrix into 2x2 pieces, apply the following to them:
                    {2⊥∊⍵}                            enlist, decode from base 2
' ▗▖▄▝▐▞▟▘▚▌▙▀▜▛█'[                                 ] index those numbers into the box drawing characters
\$\endgroup\$
  • \$\begingroup\$ 43 or 38 in Extended. \$\endgroup\$ – Adám Dec 24 '20 at 11:29
2
\$\begingroup\$

Perl 6, 159 chars (192 bytes)

(|lines.map(*~' '),'')».comb(/../).rotor(2).map:{my@d='  'xx.max(*.elems);say [~] map {"█▛▜▀▙▌▚▘▟▞▐▝▄▖▗ ".comb[:2(.trans([' ',/./]=>~⑩))]},[Z~] .map:{|$_,|@d}}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Fixed my solution. \$\endgroup\$ – bb94 Apr 23 '19 at 2:41
  • 1
    \$\begingroup\$ 143 chars \$\endgroup\$ – Jo King Apr 23 '19 at 3:05
1
\$\begingroup\$

Bash (203, 197 chars)

#!/bin/bash
r=" ▝▘▀▗▐▚▜▖▞▌▛▄▟▙█" IFS=;while read -r m;do read -r n o;for((l=${#m}>${#n}?${#m}:${#n},i=0; i<l; i+=2)){
printf -ve %-2s "${n:i:2}" "${m:i:2}";e=${e//[^ ]/1};o+=${r:2#${e// /0}:1};};echo "$o";done

or

r=" ▝▘▀▗▐▚▜▖▞▌▛▄▟▙█" IFS=
while read -r m; do
    read -r n o
    for ((l=${#m}>${#n}?${#m}:${#n},i=0; i<l; i+=2)) {
        printf -ve %-2s "${n:i:2}" "${m:i:2}"
        e=${e//[^ ]/1}
        o+=${r:2#${e// /0}:1}
    }
    echo "$o"
done
\$\endgroup\$
1
\$\begingroup\$

Perl (192 chars)

#!/usr/bin/perl -CS
use utf8;my$r=" ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█";while($v=<>){$w=<>;foreach my$i(0..length($v)/2){($x=substr($v,$i*2,2).substr($w,$i*2,2))=~s/\S/1/g;$x=~s/ /0/g;print substr($r,ord pack("b8",$x),1)}print"\n"}

or

#!/usr/bin/perl -CS
use utf8;
my $r = " ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█";
while ( $v = <> ) {
    $w = <>;
    foreach my $i ( 0 .. length($v) / 2 ) {
        ( $x = substr( $v, $i * 2, 2 ) . substr( $w, $i * 2, 2 ) ) =~ s/\S/1/g;
        $x =~ s/ /0/g;
        print substr( $r, ord pack( "b8", $x ), 1 );
    }
    print "\n";
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.