xkcd चुनौती: "स्क्रीन का प्रतिशत जो कि है [x] रंग"


57

इसलिए मुझे लगता है कि हम सभी ने शायद इस xkcd कॉमिक को देखा है :

http://imgs.xkcd.com/comics/self_description.png:

यह या तो बहुत सामान्य या बहुत कठिन हो सकता है, मुझे यकीन नहीं है। लेकिन चुनौती किसी भी भाषा में एक कार्यक्रम बनाने की है जो एक खिड़की बनाता है जिसमें कम से कम 2 रंग होते हैं और अंग्रेजी शब्दों में प्रदर्शित होता है कि स्क्रीन का प्रतिशत प्रत्येक रंग क्या है।

पूर्व। सबसे सरल समाधान काले अक्षरों के साथ एक सफेद पृष्ठभूमि होगी जो "इस छवि का प्रतिशत जो कि काला है:" को पढ़ता है: [x]%। इस छवि का प्रतिशत सफेद है: [y]% "

आप जितना चाहें उतना पागल या सरल जा सकते हैं; सादा पाठ एक मान्य समाधान है लेकिन अगर आप xkcd कॉमिक की तरह दिलचस्प चित्र बनाते हैं तो यह और भी अच्छा है! विजेता सबसे मजेदार और रचनात्मक समाधान होगा जिसे सबसे अधिक वोट मिले। तो आगे बढ़ो और कुछ मज़ेदार और योग्य बनाओ xkcd! :)

तो तुम क्या सोचते हो? एक मजेदार चुनौती की तरह लग रहा है? :)

कृपया अपने उत्तर में चल रहे अपने कार्यक्रम का स्क्रीनशॉट शामिल करें :)


6
एक "इस कार्यक्रम में 64 ए, 4 बी, ... और स्रोत कोड में 34 दोहरे उद्धरण" कार्यक्रम अधिक दिलचस्प होगा :-)
जॉन ड्वोरक

2
ठीक है ... उद्देश्य जीतने के मापदंड क्या हैं? यदि कोई विशिष्ट आउटपुट मान्य है, तो आप कैसे निर्धारित करेंगे? क्या यह पर्याप्त है कि यह सच है और यह संख्यात्मक रूप से स्वयं की संपत्ति का वर्णन करता है?
जॉन ड्वोरक

@JDDvorak ओह, यह एक अच्छा है! वर्णमाला कार्यक्रम वास्तव में है जो मुझे इस बारे में मूल रूप से सोचता है, लेकिन मैंने स्रोत कोड तत्व को इसमें जोड़ने पर विचार नहीं किया! आपको एक प्रश्न के रूप में पोस्ट करना चाहिए :) हां, यह पर्याप्त है कि यह सच है और स्वयं का वर्णन करता है। हम्म, तुम सही हो, हालांकि, मैंने नहीं सोचा था कि मैं कैसे साबित करूंगा कि अंतिम परिणाम सही थे। मुझे परिणामी छवि में प्रत्येक रंग के सभी पिक्सेल गिनने के लिए एक तरीका चाहिए होगा, मुझे लगता है। मैं अभी जाऊंगा। (क्षमा करें मेरे पहले प्रश्न में समस्याएं थीं ... मैंने कोशिश की लेकिन मैं इस पर नया हूँ! धन्यवाद :))
वेंडीकिड

यदि सत्यता और आत्म-संदर्भ पर्याप्त मानदंड हैं, तो यहां मेरी गोल्फ प्रतियोगिता प्रतियोगी है: "/.*/"(पढ़ें: [स्रोत कोड] में एक नई पंक्ति नहीं है)
जॉन ड्वोरक

@JDDvorak Hmm, मैंने आपके कोड की यहाँ कोशिश की और आउटपुट बिना कोट्स को छोड़कर कोड के समान था। शायद मैं यह सही नहीं समझा रहा हूँ, क्षमा करें। कम से कम 2 रंग उत्पन्न होने चाहिए, और अंग्रेजी वाक्य के किसी रूप में आउटपुट में सच्चे शब्द उत्पन्न होने चाहिए जो यह वर्णन करते हैं कि प्रत्येक रंग में कितने प्रतिशत स्क्रीन होती है। शायद यह एक मूर्खतापूर्ण विचार था। मैंने सोचा था कि यह मजेदार होगा लेकिन यह अभ्यास में काम नहीं कर सकता है :)
वेंडीकिड

जवाबों:


35

एल्म

नहीं देखा है किसी को भी इस खामियों का उपयोग अभी तक: डेमो

import Color exposing (hsl)
import Graphics.Element exposing (..)
import Mouse
import Text
import Window

msg a = centered <| Text.color a (Text.fromString "half the screen is this color")

type Pos = Upper | Lower

screen (w,h) (x,y) = 
  let (dx,dy) = (toFloat x - toFloat w / 2, toFloat h / 2 - toFloat y)
      ang = hsl (atan2 dy dx) 0.7 0.5
      ang' = hsl (atan2 dx dy) 0.7 0.5
      box c = case c of
        Upper -> container w (h // 2) middle (msg ang) |> color ang'
        Lower -> container w (h // 2) middle (msg ang') |> color ang
  in  flow down [box Upper, box Lower]

main = Signal.map2 screen Window.dimensions Mouse.position

यहाँ छवि विवरण दर्ज करें


3
बड़ी खामोशी!
टिमटेक

मुझे यह पसंद है!!! कम से कम अब के लिए, आप सरासर चतुर बिंदुओं के लिए चेकमार्क प्राप्त करते हैं। इसे प्यार करना!
वेंडीकिड

13
सबसे अच्छा हिस्सा है, मुझे अभी भी यकीन नहीं है कि कौन सा वाक्य किस रंग के बारे में बात कर रहा है।
ब्रिलियनड

3
view sourceShare-elm.com द्वारा वहां डाल दिया और संकलित जे एस / एचटीएमएल का हिस्सा नहीं है है।
होसियरईईईई

1
@ बीएमएल "यह" शब्द के दायरे पर निर्भर करता है। जावास्क्रिप्ट प्रोग्रामर समझ ...
hoosierEE

37

HTML के साथ जावास्क्रिप्ट

मैंने मूल कॉमिक को अधिक सटीक रूप से पुन: पेश करने की कोशिश की। एक स्क्रीनशॉट html2canvas लाइब्रेरी का उपयोग करके लिया जाता है। संख्याओं की गणना बार-बार की जाती है, इसलिए आप विंडो का आकार बदल सकते हैं या यहां तक ​​कि वास्तविक समय में पेज में कुछ जोड़ सकते हैं।

इसे ऑनलाइन आज़माएं: http://copy.sh/xkcd-688.html

यहाँ एक स्क्रीनशॉट है:

यहाँ छवि विवरण दर्ज करें

<html contenteditable>
<script src=http://html2canvas.hertzen.com/build/html2canvas.js></script>
<script>
onload = function() {
    setInterval(k, 750);
    k();
}
function k() {
    html2canvas(document.body, { onrendered: t });
}
function t(c) {
    z.getContext("2d").drawImage(c, 0, 0, 300, 150);
    c = c.getContext("2d").getImageData(0, 0, c.width, c.height).data;

    for(i = y = 0; i < c.length;) 
        y += c[i++];

    y /= c.length * 255;

    x.textContent = (y * 100).toFixed(6) + "% of this website is white";

    q = g.getContext("2d");

    q.fillStyle = "#eee";
    q.beginPath();
    q.moveTo(75, 75);
    q.arc(75,75,75,0,7,false);
    q.lineTo(75,75);
    q.fill();

    q.fillStyle = "#000";
    q.beginPath();
    q.moveTo(75, 75);
    q.arc(75,75,75,0,6.28319*(1-y),false);
    q.lineTo(75,75);
    q.fill();
}
</script>
<center>
<h2 id=x></h2>
<hr>
<table><tr>
<td>Fraction of<br>this website<br>which is white _/
<td><canvas width=150 id=g></canvas>
<td>&nbsp; Fraction of<br>- this website<br>&nbsp; which is black
</table>
<hr>
0
<canvas style="border-width: 0 0 1px 1px; border-style: solid" id=z></canvas>
<h4>Location of coloured pixels in this website</h4>

अच्छा !! Xkcd कॉमिक से समानताएं और इस तथ्य से प्यार करें कि मैं टेक्स्ट को बदल सकता हूं। साफ! : D
वेंडीकिड

1
प्रभावशाली काम ऊ
izabera

निफ्टी ... लेकिन मुझे लगता है कि इसे "समाधान" होने के लिए स्थिर करना होगा। पूरी तरह से इसके माध्यम से नहीं सोचा गया है - लेकिन चूंकि डिजिट ग्लिफ़ के एक सीमित सेट से ड्राइंग करते समय आवश्यक रूप से मनमानी परिशुद्धता के लिए कोई समाधान नहीं है, अगर आपको उच्च परिशुद्धता पर हल नहीं किया जा सकता है, तो आपको सटीक बंद करना होगा। आप कोशिश कर रहे हैं। मैं कल्पना करता हूं कि आप काले / सफेद पिक्सेल की पूर्व-गणना करने वाले एक मोनोस्पेस फॉन्ट का उपयोग करना आवश्यक होगा।
डॉ। रेम्बू

आप 3 रंगों का उपयोग कर रहे हैं, तो ग्रे के लिए प्रतिशत कहाँ हैं? ;)
एमएल

26

प्रसंस्करण, 222 वर्ण

http://i.imgur.com/eQzMGzk.png

मैं हमेशा उस कॉमिक स्ट्रिप का अपना संस्करण बनाना चाहता हूं! सबसे सरल (केवल?) तरीका मैं ऐसा करने के बारे में सोच सकता था परीक्षण और त्रुटि - कुछ ड्रा, गिनती, फिर से ड्रा करें ...

यह कार्यक्रम कुछ सेकंड के बाद एक सटीक प्रतिशत के लिए व्यवस्थित होता है। यह बहुत सुंदर नहीं है, लेकिन यह इंटरैक्टिव है ; आप विंडो का आकार बदल सकते हैं और यह पुनर्गणना करना शुरू कर देगा।

पठनीयता के लिए कुछ नए समाचार जोड़े:

float s,S,n;
int i;
void draw(){
frame.setResizable(true);
background(255);
fill(s=i=0);
text(String.format("%.2f%% of this is white",S/++n*100),10,10);
loadPixels();
while(i<width*height)if(pixels[i++]==-1)s++;
S+=s/height/width;
}

यह केवल सफेद पिक्सेल का प्रतिशत दिखाता है; पाठ के एंटीएलियासिंग के कारण, गैर-सफेद पिक्सेल आवश्यक रूप से काले नहीं होते हैं। जितना अधिक समय यह चल रहा है उतने समय में इसे स्वयं को अपडेट करने की आवश्यकता होगी।

संपादित करें:

तो, यह एक कोड-चुनौती है; मैं इसे वैसे भी गोल्फ की तरह है। हो सकता है कि मैं बाद में कुछ प्रकार के रेखांकन जोड़ सकूं, लेकिन सामान्य सिद्धांत समान रहेगा। अन्तरक्रियाशीलता मेरे विचार से साफ-सुथरा हिस्सा है।


बहुत अच्छा!! मुझे लगता है कि आपको अन्तरक्रियाशीलता का अतिरिक्त श्रेय मिलता है; मुझे खिड़की को आकार देने में मज़ा आया! बहुत अच्छा :) और तुम मेरी पहली प्रतिक्रिया हो! मुझे नहीं पता था कि कोई खेलना चाहेगा, इसलिए धन्यवाद। आपने मेरा दिन बना दिया। : डी +1! (मैं उत्सुक हूं, हालांकि यह समय के साथ धीमा क्यों हो जाता है और यह सही प्रतिशत तक पहुंचने के करीब पहुंच जाता है? मैं अभी क्या हो रहा है के लिए उत्सुक हूं; मैंने पहले कभी इस भाषा को नहीं देखा है। मैं देख रहा हूं। इस साइट के आसपास बहुत कुछ नया सामान!)
वेंडीकिड

हेडडेस्क को छोड़कर मैं गलती से +1 क्लिक करना भूल गया। अब +1 ... हाहा। माफ़ करना!
वेंडीकिड

1
आप एक और फ़ंक्शन जोड़ सकते हैं जो उपयोगकर्ताओं को माउस के साथ उस पर आकर्षित करने की अनुमति देता है, अतिरिक्त अन्तरक्रियाशीलता के लिए।
AJMansfield

7
पवित्र बॉक्स छाया, बैटमैन
बोजैंगल्स

यदि आप गोल्फ करना चाहते हैं, तो आप background(-1)background(255)
क्रिति लिथोस

20

बड़ी चुनौती। यहाँ मेरा समाधान है। मैंने मूल कॉमिक के जितना करीब संभव हो पाने की कोशिश की, मैंने xkcd फ़ॉन्ट का भी उपयोग किया ।

यह एक WPF अनुप्रयोग है, लेकिन मैं System.Drawingआलसी होने के कारण ड्राइंग भागों का उपयोग करता था।

मूल अवधारणा: डब्ल्यूपीएफ में, खिड़कियां होती हैं Visuals, जिसका अर्थ है कि उन्हें प्रदान किया जा सकता है। मैं एक बिटमैप पर पूरे विंडो उदाहरण को प्रस्तुत करता हूं, काले और कुल काले या सफेद (फ़ॉन्ट चौरसाई और सामान की अनदेखी) की गणना करता हूं और प्रत्येक छवि के प्रत्येक चरण (प्रत्येक पैनल के लिए) की गणना भी करता हूं। फिर मैं इसे फिर से एक टाइमर पर करता हूं। यह एक या दो सेकंड के भीतर संतुलन तक पहुँच जाता है।

डाउनलोड:

MEGA हमेशा वायरस, आदि के लिए आपके द्वारा डाउनलोड की गई फ़ाइलों की जाँच करें।

यदि आप इसे देखना चाहते हैं, तो आपको अपने सिस्टम के ऊपर फ़ॉन्ट स्थापित करना होगा, अन्यथा यह WPF डिफ़ॉल्ट है।

XAML:

<Window
 x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="xkcd: 688" Height="300" Width="1000" WindowStyle="ToolWindow">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.3*"/>
            <ColumnDefinition Width="0.3*"/>
            <ColumnDefinition Width="0.3*"/>
        </Grid.ColumnDefinitions>

        <Border BorderBrush="Black" x:Name="bFirstPanel" BorderThickness="3" Padding="10px" Margin="0 0 10px 0">
            <Grid>
                <Label FontSize="18" FontFamily="xkcd" VerticalAlignment="Top">Fraction of this window that is white</Label>
                <Label FontSize="18" FontFamily="xkcd" VerticalAlignment="Bottom">Fraction of this window that is black</Label>
                <Image x:Name="imgFirstPanel"></Image>
            </Grid>
        </Border>
        <Border Grid.Column="1" x:Name="bSecondPanel" BorderBrush="Black" BorderThickness="3" Padding="10px" Margin="10px 0">
            <Grid>
                <TextBlock FontSize="18" FontFamily="xkcd" VerticalAlignment="Top" HorizontalAlignment="Left">Amount of <LineBreak></LineBreak>black ink <LineBreak></LineBreak>by panel:</TextBlock>
                <Image x:Name="imgSecondPanel"></Image>
            </Grid>
        </Border>
        <Border Grid.Column="2" x:Name="bThirdPanel" BorderBrush="Black" BorderThickness="3" Padding="10px" Margin="10px 0 0 0">
            <Grid>
                <TextBlock FontSize="18" FontFamily="xkcd" VerticalAlignment="Top" HorizontalAlignment="Left">Location of <LineBreak></LineBreak>black ink <LineBreak></LineBreak>in this window:</TextBlock>
                <Image x:Name="imgThirdPanel"></Image>
            </Grid>
        </Border>

    </Grid>
</Window>

कोड:

using System;
using System.Drawing;
using System.Timers;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Brushes = System.Drawing.Brushes;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        private Timer mainTimer = new Timer();
        public MainWindow()
        {
            InitializeComponent();

            Loaded += (o1,e1) =>
                          {
                              mainTimer = new Timer(1000/10);
                              mainTimer.Elapsed += (o, e) => {
                                  try
                                  {
                                      Dispatcher.Invoke(Refresh);
                                  } catch(Exception ex)
                                  {
                                      // Nope
                                  }
                              };
                              mainTimer.Start();
                          };
        }

        private void Refresh()
        {
            var actualh = this.RenderSize.Height;
            var actualw = this.RenderSize.Width;

            var renderTarget = new RenderTargetBitmap((int) actualw, (int) actualh, 96, 96, PixelFormats.Pbgra32);
            var sourceBrush = new VisualBrush(this);

            var visual = new DrawingVisual();
            var context = visual.RenderOpen();

            // Render the window onto the target bitmap
            using (context)
            {
                context.DrawRectangle(sourceBrush, null, new Rect(0,0, actualw, actualh));
            }
            renderTarget.Render(visual);

            // Create an array with all of the pixel data
            var stride = (int) actualw*4;
            var data = new byte[stride * (int)actualh];
            renderTarget.CopyPixels(data, stride, 0);

            var blackness = 0f;
            var total = 0f;

            var blacknessFirstPanel = 0f;
            var blacknessSecondPanel = 0f;
            var blacknessThirdPanel = 0f;
            var totalFirstPanel = 0f;
            var totalSecondPanel = 0f;
            var totalThirdPanel = 0f;

            // Count all of the things
            for (var i = 0; i < data.Length; i += 4)
            {
                var b = data[i];
                var g = data[i + 1];
                var r = data[i + 2];

                if (r == 0 && r == g && g == b)
                {
                    blackness += 1;
                    total += 1;

                    var x = i%(actualw*4) / 4;

                    if(x < actualw / 3f)
                    {
                        blacknessFirstPanel += 1;
                        totalFirstPanel += 1;
                    } else if (x < actualw * (2f / 3f))
                    {
                        blacknessSecondPanel += 1;
                        totalSecondPanel += 1;
                    }
                    else if (x < actualw)
                    {
                        blacknessThirdPanel += 1;
                        totalThirdPanel += 1;
                    }
                } else if (r == 255 && r == g && g == b)
                {
                    total += 1;

                    var x = i % (actualw * 4) / 4;

                    if (x < actualw / 3f)
                    {
                        totalFirstPanel += 1;
                    }
                    else if (x < actualw * (2f / 3f))
                    {
                        totalSecondPanel += 1;
                    }
                    else if (x < actualw)
                    {
                        totalThirdPanel += 1;
                    }
                }
            }

            var black = blackness/total;

            Redraw(black, blacknessFirstPanel, blacknessSecondPanel, blacknessThirdPanel, blackness, renderTarget);
        }

        private void Redraw(double black, double firstpanel, double secondpanel, double thirdpanel, double totalpanels, ImageSource window)
        {
            DrawPieChart(black);
            DrawBarChart(firstpanel, secondpanel, thirdpanel, totalpanels);
            DrawImage(window);
        }

        void DrawPieChart(double black)
        {
            var w = (float)bFirstPanel.ActualWidth;
            var h = (float)bFirstPanel.ActualHeight;
            var padding = 0.1f;

            var b = new Bitmap((int)w, (int)h);
            var g = Graphics.FromImage(b);

            var px = padding*w;
            var py = padding*h;

            var pw = w - (2*px);
            var ph = h - (2*py);

            g.DrawEllipse(Pens.Black, px,py,pw,ph);

            g.FillPie(Brushes.Black, px, py, pw, ph, 120, (float)black * 360);

            g.DrawLine(Pens.Black, 30f, h * 0.1f, w / 2 + w * 0.1f, h / 2 - h * 0.1f);
            g.DrawLine(Pens.Black, 30f, h - h * 0.1f, w / 2 - w * 0.2f, h / 2 + h * 0.2f);

            imgFirstPanel.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(b.Width, b.Height));
        }

        void DrawBarChart(double b1, double b2, double b3, double btotal)
        {
            var w = (float)bFirstPanel.ActualWidth;
            var h = (float)bFirstPanel.ActualHeight;
            var padding = 0.1f;

            var b = new Bitmap((int)w, (int)h);
            var g = Graphics.FromImage(b);

            var px = padding * w;
            var py = padding * h;

            var pw = w - (2 * px);
            var ph = h - (2 * py);

            g.DrawLine(Pens.Black, px, py, px, ph+py);
            g.DrawLine(Pens.Black, px, py + ph, px+pw, py+ph);

            var fdrawbar = new Action<int, double>((number, value) =>
                {
                    var height = ph*(float) value/(float) btotal;
                    var width = pw/3f - 4f;

                    var x = px + (pw/3f)*(number-1);
                    var y = py + (ph - height);

                    g.FillRectangle(Brushes.Black, x, y, width, height);
                });

            fdrawbar(1, b1);
            fdrawbar(2, b2);
            fdrawbar(3, b3);

            imgSecondPanel.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(b.Width, b.Height));
        }

        void DrawImage(ImageSource window)
        {
            imgThirdPanel.Source = window;
        }
    }
}

कोड को साफ नहीं किया गया है, लेकिन यह कुछ हद तक पठनीय है, क्षमा करें।


2
एक देर से प्रवेश, लेकिन सबसे अच्छा में से एक।
प्रिमो

14

C (SDL और SDL_ttf के साथ): ग्रेस्केल समाधान

यहां एक समाधान है जो ग्रेस्केल पिक्सेल रंगों के पूर्ण स्पेक्ट्रम को कैप्चर करने के लिए पाई चार्ट फॉर्म का लाभ उठाता है, केवल 100 लाइनों के नीचे में क्लॉकिंग।

#include <stdio.h>
#include <string.h>
#include <math.h>
#include "SDL.h"
#include "SDL_ttf.h"

int main(void)
{
    SDL_Surface *screen, *buffer, *caption;
    SDL_Color pal[256];
    SDL_Rect rect;
    SDL_Event event;
    TTF_Font *font;
    int levels[256], plev[256];
    Uint8 *p;
    float g;
    int cr, redraw, hoffset, h, n, v, w, x, y;

    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();
    screen = SDL_SetVideoMode(640, 480, 0, SDL_ANYFORMAT | SDL_RESIZABLE);
    font = TTF_OpenFont(FONTPATH, 24);
    buffer = 0;
    for (;;) {
        if (!buffer) {
            buffer = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h,
                                          8, 0, 0, 0, 0);
            for (n = 0 ; n < 256 ; ++n)
                pal[n].r = pal[n].g = pal[n].b = n;
            SDL_SetColors(buffer, pal, 0, 256);
        }
        memcpy(plev, levels, sizeof levels);
        memset(levels, 0, sizeof levels);
        SDL_LockSurface(buffer);
        p = buffer->pixels;
        for (h = 0 ; h < buffer->h ; ++h) {
            for (w = 0 ; w < buffer->w ; ++w)
                ++levels[p[w]];
            p += buffer->pitch;
        }
        for (n = 1 ; n < 256 ; ++n)
            levels[n] += levels[n - 1];
        redraw = memcmp(levels, plev, sizeof levels);
        if (redraw) {
            SDL_UnlockSurface(buffer);
            SDL_FillRect(buffer, NULL, 255);
            caption = TTF_RenderText_Shaded(font,
                        "Distribution of pixel color in this image",
                        pal[0], pal[255]);
            rect.x = (buffer->w - caption->w) / 2;
            rect.y = 4;
            hoffset = caption->h + 4;
            SDL_BlitSurface(caption, NULL, buffer, &rect);
            SDL_FreeSurface(caption);
            SDL_LockSurface(buffer);
            cr = buffer->h - hoffset;
            cr = (cr < buffer->w ? cr : buffer->w) / 2 - 4;
            p = buffer->pixels;
            for (h = 0 ; h < buffer->h ; ++h) {
                y = h - (screen->h + hoffset) / 2;
                for (w = 0 ; w < buffer->w ; ++w) {
                    x = w - buffer->w / 2;
                    g = sqrtf(x * x + y * y);
                    if (g < cr - 1) {
                        g = atanf((float)y / (x + g));
                        v = levels[255] * (g / M_PI + 0.5);
                        for (n = 0 ; n < 255 && levels[n] < v ; ++n) ;
                        p[w] = n;
                    } else if (g < cr + 1) {
                        p[w] = (int)(128.0 * fabs(g - cr));
                    }
                }
                p += buffer->pitch;
            }
        }
        SDL_UnlockSurface(buffer);
        SDL_BlitSurface(buffer, NULL, screen, NULL);
        SDL_UpdateRect(screen, 0, 0, 0, 0);
        if (redraw ? SDL_PollEvent(&event) : SDL_WaitEvent(&event)) {
            if (event.type == SDL_QUIT)
                break;
            if (event.type == SDL_VIDEORESIZE) {
                SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
                                 SDL_ANYFORMAT | SDL_RESIZABLE);
                SDL_FreeSurface(buffer);
                buffer = 0;
            }
        }
    }
    SDL_Quit();
    TTF_Quit();
    return 0;
}

मेरे पिछले समाधान की तरह, फ़ॉन्ट फ़ाइल के लिए पथ को स्रोत में हार्डकोड किया जाना चाहिए या बिल्ड कमांड में जोड़ा जाना चाहिए, जैसे:

gcc -Wall -o xkcdgolf `sdl-config --cflags`
    -DFONTPATH=`fc-match --format='"%{file}"' :bold`
    xkcdgolf.c -lSDL_ttf `sdl-config --libs` -lm

कार्यक्रम का आउटपुट इस तरह दिखता है:

पूर्ण ग्रेस्केल पिक्सेल रंग वितरण को दिखाने वाला पाई चार्ट

यह देखने में मज़ेदार है, क्योंकि सभी गणित उन रीडरों को धीमा कर देते हैं जहाँ आप प्रोग्राम को स्थिर समाधान पर शून्य देख सकते हैं। पहला अनुमान बेतहाशा बंद है (चूंकि सतह पूरी तरह से काली हो जाती है), और फिर लगभग एक दर्जन या तो पुनरावृत्तियों के बाद अंतिम आकार तक सिकुड़ जाती है।

वर्तमान छवि में प्रत्येक पिक्सेल रंग की जनसंख्या गणना करके कोड काम करता है। यदि यह जनसंख्या गणना पिछले एक से मेल नहीं खाती है, तो यह छवि को फिर से खोलती है। कोड प्रत्येक पिक्सेल पर पुनरावृत्त होता है, लेकिन यह x को बदलता है, y ध्रुवीय निर्देशांक में समन्वय करता है, पहले त्रिज्या की गणना करता है (मूल के रूप में छवि के केंद्र का उपयोग करके)। यदि त्रिज्या पाई चार्ट क्षेत्र के भीतर है, तो यह थीटा की गणना करता है। थीटा को आसानी से जनसंख्या की संख्या में बदल दिया जाता है, जो पिक्सेल रंग को निर्धारित करता है। दूसरी ओर, यदि पाई चार्ट की सीमा पर त्रिज्या सही है, तो चार्ट के बाहर के चारों ओर सर्कल को खींचने के लिए एक एंटी-अलियासिड मूल्य की गणना की जाती है। ध्रुवीय निर्देशांक सब कुछ आसान बनाते हैं!


आप ज्यादातर floatगणित-पुस्तकालय कार्यों के संस्करणों का उपयोग कर रहे हैं , लेकिन तब ऐसा नहीं fabsहोना चाहिए fabsf?
लूजर ने 2 मार्च को

तकनीकी रूप से, शायद, लेकिन fabs()अधिक पोर्टेबल है।
ब्रेडबॉक्स

यह सच है, मुझे इस बात से परेशानी है कि लाइब्रेरी में मौजूद होने के बावजूद हेडर में परिभाषित नहीं किया जा सकता है। ट्रान्सेंडेंटल्स की तुलना में प्राप्त किया जाने वाला प्रदर्शन भी कम है। :)
लूज़र ने

10

C (SDL और SDL_ttf के साथ)

यहाँ C कोड की लगभग 60 लाइनों में एक बहुत ही सरल कार्यान्वयन है:

#include <stdio.h>
#include "SDL.h"
#include "SDL_ttf.h"

int main(void)
{
    char buf[64];
    SDL_Surface *screen, *text;
    SDL_Rect rect;
    SDL_Color black;
    SDL_Event event;
    TTF_Font *font;
    Uint32 blackval, *p;
    int size, b, prevb, h, i;

    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();
    screen = SDL_SetVideoMode(640, 480, 32, SDL_ANYFORMAT | SDL_RESIZABLE);
    font = TTF_OpenFont(FONTPATH, 32);
    black.r = black.g = black.b = 0;
    blackval = SDL_MapRGB(screen->format, 0, 0, 0);

    b = -1;
    for (;;) {
        prevb = b;
        b = 0;
        SDL_LockSurface(screen);
        p = screen->pixels;
        for (h = screen->h ; h ; --h) {
            for (i = 0 ; i < screen->w ; ++i)
                b += p[i] == blackval;
            p = (Uint32*)((Uint8*)p + screen->pitch);
        }
        SDL_UnlockSurface(screen);
        size = screen->w * screen->h;
        SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
        sprintf(buf, "This image is %.2f%% black pixels", (100.0 * b) / size);
        text = TTF_RenderText_Solid(font, buf, black);
        rect.x = (screen->w - text->w) / 2;
        rect.y = screen->h / 2 - text->h;
        SDL_BlitSurface(text, NULL, screen, &rect);
        SDL_FreeSurface(text);
        sprintf(buf, "and %.2f%% white pixels.", (100.0 * (size - b)) / size);
        text = TTF_RenderText_Solid(font, buf, black);
        rect.x = (screen->w - text->w) / 2;
        rect.y = screen->h / 2;
        SDL_BlitSurface(text, NULL, screen, &rect);
        SDL_FreeSurface(text);
        SDL_UpdateRect(screen, 0, 0, 0, 0);
        if (b == prevb ? SDL_WaitEvent(&event) : SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT)
                break;
            if (event.type == SDL_VIDEORESIZE)
                SDL_SetVideoMode(event.resize.w, event.resize.h, 32,
                                 SDL_ANYFORMAT | SDL_RESIZABLE);
        }
    }

    TTF_Quit();
    SDL_Quit();
    return 0;
}

इसे संकलित करने के लिए, आपको FONTPATHउपयोग करने के लिए फ़ॉन्ट की .ttf फ़ाइल को इंगित करने के लिए परिभाषित करने की आवश्यकता है :

gcc -Wall -o xkcdgolf `sdl-config --cflags`
    -DFONTPATH='"/usr/share/fonts/truetype/freefont/FreeSansBold.ttf"'
    xkcdgolf.c -lSDL_ttf `sdl-config --libs`

अधिकांश आधुनिक लिनक्स मशीनों पर आप fc-matchफ़ॉन्ट स्थानों को देखने के लिए उपयोगिता का उपयोग कर सकते हैं , इसलिए संकलन कमांड बन जाता है:

gcc -Wall -o xkcdgolf `sdl-config --cflags`
    -DFONTPATH=`fc-match --format='"%{file}"' :bold`
    xkcdgolf.c -lSDL_ttf `sdl-config --libs`

(निश्चित रूप से आप अनुरोधित फ़ॉन्ट को अपने व्यक्तिगत पसंदीदा से बदल सकते हैं।)

कोड विशेष रूप से एंटी-अलियासिंग का अनुरोध करता है, ताकि खिड़की में केवल काले और सफेद पिक्सेल हों।

अंत में, मैं खिड़की के आकार बदलने की अनुमति देने के लिए @ daniero के सुरुचिपूर्ण समाधान से प्रेरित था। आप देखेंगे कि कभी-कभी यह प्रोग्राम काउंट्स के बीच दोलन करता है, एक आकर्षण के चारों ओर एक कक्षा में अटक जाता है जो कभी भी नहीं पहुंच सकता है। जब ऐसा होता है, तब तक खिड़की को थोड़ा सा आकार दें, जब तक कि यह बंद न हो जाए।

और, अनुरोध के अनुसार, जब मैं इसे अपने सिस्टम पर चलाता हूं, तो यह कैसा दिखता है:

यह छवि 3.36% काले पिक्सेल और 96.64% सफेद पिक्सेल है।

अंत में, मुझे लगता है कि मुझे इशारा करना चाहिए, अगर किसी ने पहले से ही इसे नहीं देखा है, तो यह कि एमएए ने रान्डेल मुनरो के साथ एक साक्षात्कार प्रकाशित किया, जिसमें उन्होंने कुछ विस्तार से कार्टून # 688 बनाने पर चर्चा की।


1
बहुत अच्छा समाधान है। क्या आप संभवतः @ daniero की पोस्ट के बाद चल रहे प्रोग्राम के कुछ स्क्रीनशॉट में डाल सकते हैं? :)
एलेक्स ब्रूक्स

+1, बहुत अच्छा! स्क्रीनशॉट जोड़ने के लिए धन्यवाद :) और साक्षात्कार लिंक दिलचस्प है, धन्यवाद!
वेंडीकिड

9

यहाँ छवि विवरण दर्ज करें

छवि 100x100 है और संख्याएं सटीक हैं, और मेरा मतलब सटीक है - मैंने 10000 पिक्सेल की छवि को चुना ताकि प्रतिशत दो दशमलव स्थानों के साथ व्यक्त किए जा सकें। यह विधि थोड़ी गणित, अनुमान लगाने की थोड़ी और पायथन में कुछ संख्या में क्रंचिंग थी।

जैसा कि मुझे पहले से पता था कि प्रतिशत 4 अंकों में व्यक्त किए जा सकते हैं, मैंने गिना कि प्रत्येक अंक 0 में 9 के माध्यम से 8 पिक्सेल उच्च एरियल में कितने काले पिक्सेल थे, यही पाठ में लिखा गया है। त्वरित फ़ंक्शन weightजो आपको बताता है कि किसी दिए गए नंबर को लिखने के लिए कितने पिक्सेल की आवश्यकता है, बाईं ओर 4 अंकों के लिए शून्य के साथ गद्देदार:

def weight(x):
    total = 4 * px[0]
    while x > 0:
       total = total - px[0] + px[x % 10]
       x = x / 10
    return total

pxआवश्यक पिक्सल की संख्या के लिए एक सरणी मानचित्रण अंक है। यदि B काले पिक्सेल की संख्या है, और W सफेद पिक्सेल की संख्या है, तो हमारे पास है B + W = 10000, और हमें इसकी आवश्यकता है:

B = 423 + weight(B) + weight(W)
W = 9577 - weight(B) - weight(W)

कॉन्स्टेंट कहां से आए? 423 ब्लैक पिक्सल्स की "प्रारंभिक" संख्या है, बिना नंबरों के टेक्स्ट में ब्लैक पिक्सल्स की संख्या। 9577 प्रारंभिक सफेद पिक्सेल की संख्या है। मुझे लगातार ब्लैक पिक्सल्स की मात्रा को कई बार समायोजित करना पड़ा, इससे पहले कि मैं निरंतरता प्राप्त कर पाऊं ताकि उपरोक्त प्रणाली का भी समाधान हो। यह अनुमान लगाने और मेरी उंगलियों को पार करने के द्वारा किया गया था।

उपरोक्त प्रणाली बुरी तरह से गैर-रैखिक है, इसलिए स्पष्ट रूप से आप इसे प्रतीकात्मक रूप से हल करने के बारे में भूल सकते हैं, लेकिन आप जो कर सकते हैं वह बी के हर मूल्य के माध्यम से लूप है, डब्ल्यू = 10000 - बी सेट करें, और समीकरणों को स्पष्ट रूप से जांचें।

>>> for b in range(10000 + 1):
...     if b == weight(b) + weight(10000 - b)+423: print b;
...
562
564

हो सकता है कि एक 250 x 400 छवि ऐसा करें ताकि आप इसे 3 दशमलव स्थानों पर प्राप्त कर सकें और इस बीच अधिक पाठ प्रदर्शित कर सकें।
जो

बहुत अच्छा समाधान, कुछ जानवर बल गणित हमेशा इस तरह की समस्याओं को हल कर सकते हैं!
CCP

6

QBasic

क्योंकि विषाद।

और क्योंकि मैं वास्तव में किसी भी छवि पुस्तकालयों पता नहीं है आधुनिक भाषाओं है।

SCREEN 9

CONST screenWidth = 640
CONST screenHeight = 350
CONST totalPixels# = screenWidth * screenHeight

accuracy = 6

newWhite# = 0
newGreen# = 0
newBlack# = totalPixels#

DO
    CLS
    white# = newWhite#
    green# = newGreen#
    black# = newBlack#

    ' Change the precision of the percentages every once in a while
    ' This helps in finding values that converge
    IF RND < .1 THEN accuracy = INT(RND * 4) + 2
    format$ = "###." + LEFT$("######", accuracy) + "%"

    ' Display text
    LOCATE 1
    PRINT "Percentage of the screen which is white:";
    PRINT USING format$; pct(white#)
    LOCATE 4
    PRINT white#; "/"; totalPixels#; "pixels"
    LOCATE 7
    PRINT "Percentage of the screen which is black:";
    PRINT USING format$; pct(black#)
    LOCATE 10
    PRINT black#; "/"; totalPixels#; "pixels"
    LOCATE 13
    PRINT "Percentage of the screen which is green:";
    PRINT USING format$; pct(green#)
    LOCATE 16
    PRINT green#; "/"; totalPixels#; "pixels"

    ' Display bar graphs
    LINE (0, 16)-(pct(white#) / 100 * screenWidth, 36), 2, BF
    LINE (0, 100)-(pct(black#) / 100 * screenWidth, 120), 2, BF
    LINE (0, 184)-(pct(green#) / 100 * screenWidth, 204), 2, BF

    newBlack# = pixels#(0)
    newGreen# = pixels#(2)
    newWhite# = pixels#(15)
LOOP UNTIL black# = newBlack# AND white# = newWhite# AND green# = newGreen#

' Wait for user keypress before ending program: otherwise the "Press any
' key to continue" message would instantly make the results incorrect!
x$ = INPUT$(1)


FUNCTION pixels# (colr)
' Counts how many pixels of the given color are on the screen

pixels# = 0

FOR i = 0 TO screenWidth - 1
    FOR j = 0 TO screenHeight - 1
        IF POINT(i, j) = colr THEN pixels# = pixels# + 1
    NEXT j
NEXT i

END FUNCTION

FUNCTION pct (numPixels#)
' Returns percentage, given a number of pixels

pct = numPixels# / totalPixels# * 100

END FUNCTION

बहुत ही सीधा-साधा आउटपुट-गिनती-रिपीट विधि। मुख्य "दिलचस्प" बात यह है कि कार्यक्रम यादृच्छिक रूप से प्रतिशत के लिए विभिन्न पूर्वाग्रहों की कोशिश करता है - मैंने पाया कि यह हमेशा अन्यथा रूपांतरित नहीं हुआ।

और आउटपुट ( QB64 पर परीक्षण किया गया ):

QBasic पैराग्राफ


3

AWK

... netpbm और अन्य सहायकों के साथ

'X' फ़ाइल:

BEGIN {
        FS=""
        n++
        while(n!=m) {
                c="printf '%s\n' '"m"% black pixels'"
                c=c" '"100-m"% white pixels'"
                c=c" | pbmtext -space 1 -lspace 1 | pnmtoplainpnm | tee x.pbm"
                n=m
                delete P
                nr=0
                while(c|getline==1) if(++nr>2) for(i=1;i<=NF;i++) P[$i]++
                close(c)
                m=100*P[1]/(P[0]+P[1])
                print m"%"
        }
}

दौड़:

$ awk -f x
4.44242%
5.2424%
5.04953%
5.42649%
5.27746%
5.1635%
5.15473%
5.20733%
5.20733%

तस्वीर को 'x.pbm' के रूप में लिखा गया है, मैंने इसे अपलोड करने के लिए पीएनजी में बदल दिया:

x.png

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.