भूख छवि साँप - छेद # 3


25

छेद # 1

जो साँप भूखा है।

वह एक समय में एक पिक्सेल, चित्र खाता है।

वह वास्तव में उज्ज्वल पिक्सेल पसंद करता है।

चुनौती

प्रोग्राम जो सबसे उज्ज्वल पिक्सल खाने के लिए वह पा सकता है, यह देखते हुए कि वह केवल ऊपर, नीचे, बाएं या दाएं घूम सकता है।

विशेष विवरण

  • जो छवि के ऊपरी बाएँ पिक्सेल पर शुरू होना चाहिए।
  • जो केवल क्षैतिज या लंबवत रूप से 1 प्रत्येक चाल से आगे बढ़ सकता है
  • जो के पास चित्र में पिक्सेल की मात्रा का 1/3 स्थानांतरित करने के लिए केवल पर्याप्त समय है (1/3 पिक्सल के रूप में कई चालें)। यदि पिक्सेल की संख्या 3 से अधिक नहीं है, तो निकटतम पूर्णांक तक गोल करें।
  • जो अपने रास्ते को पार कर सकता है, हालांकि यह 0 चमक के रूप में गिना जाता है
  • चमक r, g और b के योग पर आधारित है, इसलिए rgb (0,0,0) में 0 की चमक है जबकि rgb (255,255,255) में अधिकतम चमक है।

इनपुट

आप अपनी पसंद के अनुसार छवि इनपुट कर सकते हैं।

उत्पादन

  • आपकी तस्वीर का अंतिम परिणाम दिखाने वाली छवि (काले पिक्सेल खाए जा रहे हैं)।
  • खाने की चमक की मात्रा (कृपया अपने जवाब में क्या सीमा निर्दिष्ट करें)

स्कोरिंग

आपके कार्यक्रम को इस पर वर्गीकृत किया जाएगा:

  • पिक्सेल की औसत चमक जो खाती है / चित्र में पिक्सेल की औसत चमक *

* आप अपने कार्यक्रम में इसे हार्डकोड कर सकते हैं

आपका कुल स्कोर निम्नलिखित छवियों के लिए औसत अंक होगा:

परीक्षण चित्र:

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

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

http://upload.wikimedia.org/wikipedia/en/thumb/f/f4/The_Scream.jpg/800px-The_Scream.jpg

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

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

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


3
फन मार्कडाउन तथ्य - आप छवियों को उनके मूल के लिंक में बदल सकते हैं [![image description](SE URL for downsized image)](URL for original image):।
केल्विन के शौक

1
यह एक विचार हो सकता है कि लोग अपने जवाबों में एक उदाहरण "खाया" छवि को शामिल करने के लिए कहें।
नथानियल

जवाबों:


16

सी ++, स्कोर: १.४२,०४२ १.४६,७६६

यह मूल रूप से दो मौजूदा समाधानों का थोड़ा अधिक परिष्कृत संस्करण है: चार संभावित चालों में, यह उस चमक का अधिकतम चयन करता है। हालांकि, केवल लक्ष्य पिक्सेल की चमक को देखने के बजाय, यह लक्ष्य पिक्सेल के पड़ोस में पिक्सेल-चमक की भारित राशि को देखता है, जहां लक्ष्य के करीब पिक्सेल का वजन अधिक होता है।

EDIT: पड़ोस गणना में नॉनलाइन चमक का उपयोग करने से स्कोर में थोड़ा सुधार होता है।

के साथ संकलित करें g++ joe.cpp -ojoe -std=c++11 -O3 -lcairo। कैरो की आवश्यकता है।

के साथ भागो joe <image-file> [<radius>]<image-file>इनपुट PNG इमेज है। <radius>(वैकल्पिक तर्क) सम-ओवर पड़ोस का त्रिज्या है, पिक्सेल में (छोटा तेज है, बड़ा है (लगभग) बेहतर है।) स्कोर और एक छवि का नाम आउटपुट करता है out.<image-file>

#include <cairo/cairo.h>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>

using namespace std;

int main(int argc, const char* argv[]) {
    auto* img = cairo_image_surface_create_from_png(argv[1]);
    int width = cairo_image_surface_get_width(img),
        height = cairo_image_surface_get_height(img),
        stride = cairo_image_surface_get_stride(img);
    unsigned char* data = cairo_image_surface_get_data(img);

    double* brightness = new double[width * height];
    double total_brightness = 0;
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            const unsigned char* p = data + stride * y + 4 * x;
            total_brightness += brightness[y * width + x] = p[0] + p[1] + p[2];
        }
    }

    const int r = argc > 2 ? stoi(argv[2]) : 64, R = 2 * r + 1;
    double* weight = new double[R * R];
    for (int y = -r; y <= r; ++y) {
        for (int x = -r; x <= r; ++x)
            weight[R * (y + r) + (x + r)] = 1.0 / (x*x + y*y + 1);
    }

    auto neighborhood = [&] (int x, int y) {
        double b = 0;
        int x1 = max(x - r, 0), x2 = min(x + r, width - 1);
        int y1 = max(y - r, 0), y2 = min(y + r, height - 1);
        for (int v = y1; v <= y2; ++v) {
            const double *B = brightness + width * v + x1;
            const double *W = weight + R * (v - (y - r)) + (x1 - (x - r));
            for (int u = x1; u <= x2; ++u, ++B, ++W)
                b += (*W) * (*B) * (*B);
        }
        return b;
    };

    int n = (2 * width * height + 3) / 6;
    int x = 0, y = 0;
    double path_brightness = 0;
    int O[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    for (int i = 0; i < n; ++i) {
        if (i % 1000 == 0) cerr << (200 * i + n) / (2 * n) << "%\r";

        path_brightness += brightness[width * y + x]; brightness[width * y + x] = 0;
        unsigned char* p = data + stride * y + 4 * x;
        p[0] = p[1] = 16 * i % 255; p[2] = 0;

        auto O_end = partition(begin(O), end(O), [&] (const int* o) {
            return x + o[0] >= 0 && x + o[0] < width &&
                   y + o[1] >= 0 && y + o[1] < height;
        });
        const int* o_max; double o_max_neighborhood = -1;
        for (auto o = O; o != O_end; ++o) {
            double o_neighborhood = neighborhood(x + (*o)[0], y + (*o)[1]);
            if (o_neighborhood > o_max_neighborhood)
                o_max = *o, o_max_neighborhood = o_neighborhood;
        }
        x += o_max[0]; y += o_max[1];
    }

    cout << (path_brightness * width * height) / (n * total_brightness) << endl;

    cairo_surface_write_to_png(img, (string("out.") + argv[1]).c_str());

    delete []brightness;
    delete []weight;
    cairo_surface_destroy(img);
}

परिणाम

Bridge    1.39945
Balls     1.77714
Scream    1.38349
Fractal   1.31727
Vortex    1.66493
Tornado   1.26366
-----------------
Average   1.46766

पुल बॉल्स चीख भग्न भंवर बवंडर

अधिक आँख कैंडी

भंवर एनीमेशन बवंडर एनीमेशन


मैं सिर्फ अपने खुद के कुछ नमूना चित्रों पर आपके कार्यक्रम की कोशिश करता हूं, और किसी के पास केवल शुरुआत बिंदु के आसपास बहुत अधिक काला है, और वहां आपके कार्यक्रम के दुर्घटनाग्रस्त होने के कारण लैम्ब्डा नाएन लौट रहा है।
प्लाज़्मा एचएच

@PlasmaHH आपत्तिजनक छवि साझा करने का मन?
एल

मैं इसे छुट्टी की छवियों को खिला रहा था ... 400x400 शुद्ध काला "चाल" भी करता है।
प्लाज़्मा एचएच

@PlasmaHH खैर, विशुद्ध रूप से काली छवि में एक अपरिभाषित स्कोर है, यह शून्य से अधिक शून्य है, जो कि एक NaN होगा। यह पड़ोस की गणना को प्रभावित नहीं करना चाहिए, हालांकि, या कार्यक्रम को दुर्घटनाग्रस्त कर सकता है (हालांकि यह फ्लोटिंग-पॉइंट पर्यावरण पर निर्भर हो सकता है।)
एल

O_max पॉइंटर पर एक नज़र डालें if (o_neighborhood > o_max_neighborhood) o_max = *o, o_max_neighborhood = o_neighborhood; केवल यह कोड इसे सेट करता है। हालाँकि नैन शामिल होने के कारण, तुलना हमेशा झूठी होती है, इस प्रकार o_max को कभी भी सेट नहीं किया जाता है और इसका उपयोग अनैतिक तरीके से किया जाता है।
प्लाज़्मा एचएच

7

पायथन 3, स्कोर = 1.57

पहले हमारा साँप एक दूसरे से समान दूरी के साथ खड़ी रेखाएँ बनाता हुआ चित्र बनाता है।

ए

हम एक ऊर्ध्वाधर रेखा में एक दूसरे के बगल में दो बिंदु लेकर और एक लूप बनाकर इस सांप का विस्तार कर सकते हैं जिनके अंत बिंदु हैं।

|      |
|  =>  +----+
|      +----+
|      |

हम बिंदुओं को जोड़े में व्यवस्थित करते हैं और प्रत्येक जोड़ी के लिए हम लूप के आकार और औसत चमक मूल्य को संग्रहीत करते हैं जो सबसे बड़ी औसत चमक देता है।

प्रत्येक चरण में हम उच्चतम मूल्य के साथ जोड़ी चुनते हैं विस्तार पर अधिकतम औसत चमक प्राप्त करने के लिए अपने लूप का विस्तार करते हैं और जोड़ी के लिए नए इष्टतम लूप आकार और चमक मूल्य की गणना करते हैं।

हम मान द्वारा क्रमबद्ध ढेर संरचना में मूल्य (मान, आकार, बिंदु_पेयर) को संग्रहीत करते हैं ताकि हम सबसे बड़े तत्व (ओ (1)) को हटा सकें और नए संशोधित एक (ओ (लॉग एन)) को कुशलता से जोड़ सकें।

जब हम पिक्सेल गणना सीमा तक पहुँचते हैं तो हम रुक जाते हैं और वह साँप अंतिम साँप होगा।

परिणामों में ऊर्ध्वाधर रेखाओं के बीच की दूरी बहुत कम प्रभाव डालती है इसलिए लगातार 40 पिक्सेल चुना गया था।

परिणाम

swirl    1.33084397946
chaos    1.76585674741
fractal  1.49085737611
bridge   1.42603926741
balls    1.92235115238
scream   1.48603818637
----------------------
average  1.57033111819

ए ए ए ए ए ए

नोट: मूल "द स्क्रीम" तस्वीर उपलब्ध नहीं थी इसलिए मैंने समान रिज़ॉल्यूशन के साथ एक अन्य "द स्क्रीम" तस्वीर का उपयोग किया।

जिफ़ ने सांप को "जलतरंग" की छवि पर विस्तारित प्रक्रिया दिखाते हुए कहा:

ए

कोड स्टड से एक (या अधिक स्थान अलग) फ़ाइल नाम लेता है और परिणामस्वरूप साँप छवियों को पीएनजी फ़ाइलों को लिखता है और स्कोर को स्टडआउट करने के लिए प्रिंट करता है।

from PIL import Image
import numpy as np
import heapq as hq

def upd_sp(p,st):
    vs,c=0,0
    mv,mp=-1,0
    for i in range(st,gap):
        if p[1]+i<h:
            vs+=v[p[0],p[1]+i]+v[p[0]+1,p[1]+i]
            c+=2
            if vs/c>mv:
                mv=vs/c
                mp=i
    return (-mv,mp)

mrl=[]
bf=input().split()

for bfe in bf:
    mr,mg=0,0    
    for gap in range(40,90,1500):

        im=Image.open(bfe)
        im_d=np.asarray(im).astype(int)

        v=im_d[:,:,0]+im_d[:,:,1]+im_d[:,:,2]

        w,h=v.shape

        fp=[]
        sp=[]
        x,y=0,0
        d=1

        go=True
        while go:
            if 0<=x+2*d<w:
                fp+=[(x,y)]
                fp+=[(x+d,y)]
                sp+=[(x-(d<0),y)]
                x+=2*d
                continue
            if y+gap<h:
                for k in range(gap):
                    fp+=[(x,y+k)]
                y+=gap
                d=-d
                continue
            go=False

        sh=[]
        px=im.load()

        pl=[]

        for p in fp:
            pl+=[v[p[0],p[1]]]
            px[p[1],p[0]]=(0,127,0)   

        for p in sp:
            mv,mp=upd_sp(p,1)
            if mv<=0:
                hq.heappush(sh,(mv,1,mp+1,p))

        empty=False
        pleft=h*w//3
        pleft-=len(fp)
        while pleft>gap*2 and not empty:

            if len(sh)>0:
                es,eb,ee,p=hq.heappop(sh)
            else:
                empty=True
            pleft-=(ee-eb)*2

            mv,mp=upd_sp(p,ee)
            if mv<=0:
                hq.heappush(sh,(mv,ee,mp+1,p))    

            for o in range(eb,ee):
                pl+=[v[p[0],p[1]+o]]
                pl+=[v[p[0]+1,p[1]+o]]
                px[p[1]+o,p[0]]=(0,127,0)   
                px[p[1]+o,p[0]+1]=(0,127,0)

        pl+=[0]*pleft

        sb=sum(pl)/len(pl)
        ob=np.sum(v)/(h*w)

        im.save(bfe[:-4]+'snaked.png')

        if sb/ob>mr:
            mr=sb/ob
            mg=gap

    print(bfe,mr)
    mrl+=[mr]

print(sum(mrl)/len(mrl))

5

पायथन 2 (स्कोर: 0.0797116)

गेंद को लुढ़काने के लिए बस एक बहुत ही सरल और भोली लालची एल्गोरिथ्म।

#!/usr/bin/python

from PIL import Image

OFFSETS = [(-1, 0), (0, -1), (1, 0), (0, 1)]
def test_img(filename):
    img = Image.open(filename)

    joe, eaten = (0, 0), []
    img_w, img_h = img.size
    all_pixels = [
        sum(img.getpixel((x, y)))
        for x in xrange(img_w)
        for y in xrange(img_h)
    ]
    total_brightness = float(sum(all_pixels)) / len(all_pixels)

    for _ in xrange(0, (img_w*img_h)/3):
        max_offset, max_brightness = (0, 0), 0
        for o in OFFSETS:
            try:
                brightness = sum(img.getpixel((joe[0] + o[0], joe[1] + o[1])))
            except IndexError:
                brightness = -1
            if brightness >= max_brightness:
                max_offset = o
                max_brightness = brightness

        joe = (joe[0] + max_offset[0], joe[1] + max_offset[1])
        eaten.append(max_brightness)
        img.putpixel(joe, (0, 0, 0))

    eaten_brightness = float(sum(eaten)) / len(eaten)
    print('%d of %d (score %f)' % (eaten_brightness, total_brightness, eaten_brightness / total_brightness))
    img.show()

test_img('img0.jpg')
test_img('img1.png')
test_img('img2.jpg')
test_img('img3.jpg')
test_img('img4.jpg')

आउटपुट:

llama@llama:~/Code/python/ppcg40069hungrysnake$ ./hungrysnake.py 
15 of 260 (score 0.060699)
9 of 132 (score 0.074200)
16 of 300 (score 0.055557)
4 of 369 (score 0.010836)
79 of 400 (score 0.197266)

1
मुझे लगता है कि आपका स्कोरिंग बंद है। यह पूरी तस्वीर के लिए औसत चमक पर खाए गए जो की चमक का औसत है ... एक यादृच्छिक जो को लगभग 1. का स्कोर मिलना चाहिए
स्ट्रेच

@StretchManiac हम्म, मैं कुछ भी गलत नहीं देखता। sum of brightnesses of eaten pixels / amount of eaten pixelsसही सूत्र है, सही है? ); हो सकता है कि यह सिर्फ एक सच में भयानक एल्गोरिथ्म है
दरवाज़े

@ डॉर्कनोब यह हैThe average brightness of pixels Joe eats / The average brightness of the pixels in the picture*
hmatt1

नारंगी और काले घुंघराले (नीला नहीं) के लिए, मुझे 68.0846 की औसत चमक मिली ... जो कि आप में से किसी से मेल नहीं खाती। शायद योग (getPixel (...)) क्या आप चाहते हैं वापस नहीं करता है? (मैं एक अजगर नौसिखिया थोड़े है)। BTW, 6 तस्वीरें हैं, लेकिन आपके पास केवल 5 आउटपुट हैं। क्या आप भी किसी तरह तस्वीरों को लेबल कर सकते हैं?
स्ट्रेच

@StretchManiac आप अपनी चमक की गणना कैसे कर रहे हैं? मेरा सिर्फ R, G, और B मानों को सम्‍मिलित करता है। क्षमा करें, मैं उस एक को याद करता हूं जो दूसरे-से-अंतिम (आपकी टिप्पणी में आपके द्वारा उल्लेखित है, मुझे लगता है) आता है। मैं इसे सुबह जोड़ दूंगा (मुझे अभी सोना है)।
दरवाज़े

5

जावा (स्कोर: 0.6949)

एक साधारण एल्गोरिथ्म जो वर्तमान पिक्सेल के आसपास के चार पिक्सेल में से सबसे उज्ज्वल पिक्सेल खाता है। एक टाई के मामले में, खाए गए पिक्सेल यादृच्छिक होते हैं, जिससे अलग-अलग स्कोर होते हैं और परिणामस्वरूप प्रत्येक निष्पादन होता है। जैसे, नीचे दिए गए स्कोर प्रत्येक छवि पर 50 से अधिक निष्पादन का औसत हैं।

इसे चलाने के लिए, या तो स्रोत में तीन तर्कों (वर्ग स्थिरांक के रूप में मौजूदा) को संपादित करें, या उन्हें कमांड लाइन के माध्यम से उस रूप में पास करें java HungryImageSnake <source> <iterations> <printScores>जहां <source>खाने के लिए छवि की स्रोत फ़ाइल है, छवि खाने के <iterations>लिए कई बार है (लेने औसत स्कोर और सभी पुनरावृत्तियों पर सर्वश्रेष्ठ स्कोर की बचत), और <printScores>प्रत्येक पुनरावृत्ति के अंक को प्रिंट करना या न करने के लिए गलत है।

import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

public class HungryImageSnake {

    private static final String SOURCE = "tornado.jpg";
    private static final int ITERATIONS = 50;
    private static final boolean PRINT_SCORES = true;

    public static void main(String[] args) {
        try {
            String source = args.length > 0 ? args[0] : SOURCE;
            int iterations = args.length > 1 ? Integer.parseInt(args[1]) : ITERATIONS;
            boolean printScores = args.length > 2 ? Boolean.parseBoolean(args[2]) : PRINT_SCORES;

            System.out.printf("Reading '%s'...%n", source);
            System.out.printf("Performing %d meals...%n", iterations);
            BufferedImage image = ImageIO.read(new File(source));
            double totalScore = 0;
            double bestScore = 0;
            BufferedImage bestImage = null;
            for (int i = 0; i < iterations; i++) {
                HungryImageSnake snake = new HungryImageSnake(image);
                while (snake.isHungry()) {
                    snake.eat();
                }
                double score = snake.getScore();
                if (printScores) {
                    System.out.printf("    %d: score of %.4f%n", i + 1, score);
                }
                totalScore += score;
                if (bestImage == null || score > bestScore) {
                    bestScore = score;
                    bestImage = snake.getImage();
                }
            }
            System.out.printf("Average score: %.4f%n", totalScore / iterations);
            String formattedScore = String.format("%.4f", bestScore);
            String output = source.replaceFirst("^(.*?)(\\.[^.]+)?$", "$1-b" + formattedScore + "$2");
            ImageIO.write(bestImage, source.substring(source.lastIndexOf('.') + 1), new File(output));
            System.out.printf("Wrote best image (score: %s) to '%s'.%n", bestScore, output);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private int x;
    private int y;
    private int movesLeft;
    private int maximumMoves;
    private double eatenAverageBrightness;
    private double originalAverageBrightness;
    private BufferedImage image;

    public HungryImageSnake(BufferedImage image) {
        this.image = copyImage(image);
        int size = image.getWidth() * image.getHeight();
        this.maximumMoves = size / 3;
        this.movesLeft = this.maximumMoves;
        int totalBrightness = 0;
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                totalBrightness += getBrightnessAt(x, y);
            }
        }
        this.originalAverageBrightness = totalBrightness / (double) size;
    }

    public BufferedImage getImage() {
        return image;
    }

    public double getEatenAverageBrightness() {
        return eatenAverageBrightness;
    }

    public double getOriginalAverageBrightness() {
        return originalAverageBrightness;
    }

    public double getScore() {
        return eatenAverageBrightness / originalAverageBrightness;
    }

    public boolean isHungry() {
        return movesLeft > 0;
    }

    public void eat() {
        if (!isHungry()) {
            return;
        }
        int[][] options = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        shuffleArray(options); // prevent snake from getting stuck in corners
        int[] bestOption = null;
        int bestBrightness = 0;
        for (int[] option : options) {
            int optionX = this.x + option[0];
            int optionY = this.y + option[1];
            if (exists(optionX, optionY)) {
                int brightness = getBrightnessAt(optionX, optionY);
                if (bestOption == null || brightness > bestBrightness) {
                    bestOption = new int[]{ optionX, optionY };
                    bestBrightness = brightness;
                }
            }
        }

        image.setRGB(bestOption[0], bestOption[1], 0);
        this.movesLeft--;
        this.x = bestOption[0];
        this.y = bestOption[1];
        this.eatenAverageBrightness += bestBrightness / (double) maximumMoves;
    }

    private boolean exists(int x, int y) {
        return x >= 0 && x < image.getWidth() && y >= 0 && y < image.getHeight();
    }

    private int getBrightnessAt(int x, int y) {
        int rgb = image.getRGB(x, y);
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = rgb & 0xFF;
        return r + g + b;
    }

    private static <T> void shuffleArray(T[] array) {
        Random random = new Random();
        for (int i = array.length - 1; i > 0; i--) {
            int index = random.nextInt(i + 1);
            T temp = array[index];
            array[index] = array[i];
            array[i] = temp;
        }
    }

    private static BufferedImage copyImage(BufferedImage source){
        BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());
        Graphics g = b.getGraphics();
        g.drawImage(source, 0, 0, null);
        g.dispose();
        return b;
    }
}

औसत स्कोर, छवि से, पचास पुनरावृत्तियों पर:

Bridge - 0.7739
Spheres - 0.5580
Scream - 0.8197
Fractal - 0.3850
Vortex - 0.9158
Tornado - 0.7172

सर्वश्रेष्ठ स्कोर, छवि द्वारा, एक ही पचास पुनरावृत्तियों पर:

Bridge - 0.8996
Spheres - 0.8741
Scream - 0.9183
Fractal - 0.5720
Vortex - 1.1520
Tornado - 0.9281

उच्चतम स्कोरिंग रन की छवियां:

ब्रिज - 0.8996 गोलाकार - 0.8741 चीख - 0.9183 भग्न - 0.5720 भंवर - 1.1520 बवंडर - 0.9281

जैसा कि छवियों से स्पष्ट है, पिक्सल के एक तिहाई से भी कम वास्तव में खाया जाता है, क्योंकि साँप कभी-कभी पिक्सेल के बीच फंस जाता है, जो पहले से ही खाया गया है, जिस पर वह मृत क्षेत्र के भीतर तब तक अटका रहता है जब तक कि उसके आंदोलनों की यादृच्छिकता इसे नहीं लाती। छवि का एक खाद्य भाग।

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

बेशक, एक बेहतर तरीका यह होगा कि प्रत्येक पिक्सेल के लिए किसी प्रकार की चमक हेयुरिस्टिक बनाई जाए और width * height / 3उच्चतम औसत चमक के साथ पिक्सेल का मार्ग खोजें , लेकिन मुझे संदेह है कि यह दृष्टिकोण रन टाइम में, विशेष रूप से बड़ी छवियों पर, संख्या के रूप में इष्टतम होगा। संभावित क्रमपरिवर्तन बहुत बड़े होंगे। मैं बाद में इस दृष्टिकोण के कुछ रूप में एक शॉट ले सकता हूं और यदि ऐसा है तो एक अलग उत्तर में पोस्ट कर सकता हूं।


अगर किसी को मेरा जवाब कितना बड़ा है (इस चित्र में) के कारण परेशान किया गया है, तो मुझे बताएं और मैं छवियों को लिंक या किसी अन्य कम-स्पैस विकल्प के पक्ष में हटा दूंगा। या, अगर किसी को "खाया" छवियों का पूर्ण संकल्प मूल पसंद आएगा, तो मुझे एक टिप्पणी में भी बताएं।
FThompson

4

पायथन 2, स्कोर: 1.205

मैंने कुछ समय पहले एक त्वरित पायथन समाधान को एक साथ रखा, लेकिन इसे पोस्ट करना भूल गया। यही पर है। यह छवि में सबसे अमीर ब्लॉकों को ढूंढता है, फिर प्रत्येक ब्लॉक में यात्रा करता है, इसमें आने वाले सभी सर्वोत्तम ब्लॉकों को खाता है।

परिणाम

bridge.jpg: 591.97866/515.41501 =                               1.14855 
BallsRender.png: 493.24711/387.80635 =                          1.27189 
Mandel_zoom_04_seehorse_tail.jpg: 792.23990/624.60579 =         1.26838 
Red_Vortex_Apophysis_Fractal_Flame.jpg: 368.26121/323.08463 =   1.13983 
The_Scream.jpg: 687.18565/555.05221 =                           1.23806
swirl.jpg: 762.89469/655.73767 =                                1.16341

AVERAGE                                                         1.205

उदाहरण चित्र

संसाधित पुल चित्र

पायथन 2.7 कोड

from pygame.locals import *
import pygame, sys, random

fn = sys.argv[1]

screen = pygame.display.set_mode((1900,1000))
pic = pygame.image.load(fn)
pic.convert()
W,H = pic.get_size()
enough = W*H/3
screen.blit(pic, (0,0))

ORTH = [(-1,0), (1,0), (0,-1), (0,1)]
def orth(p):
    return [(p[0]+dx, p[1]+dy) for dx,dy in ORTH]

def look(p):
    x,y = p
    if 0 <= x < W and 0 <= y < H:
        return sum(pic.get_at(p))
    else:
        return -1

# index picture
locs = [(x,y) for x in range(W) for y in range(H)]
grid = dict( (p,sum(pic.get_at(p))) for p in locs )
rank = sorted( grid.values() )
median = rank[ len(rank)/2 ]
dark = dict( (k,v) for k,v in grid if v < median )
good = dict( (k,v) for k,v in grid if v > median )
pictotal = sum(rank)
picavg = 1.0 * pictotal/(W*H)
print('Indexed')

# compute zone values:
block = 16
xblocks, yblocks = (W-1)/block, (H-1)/block
zones = dict( ((zx,zy),0) for zx in range(xblocks) for zy in range(yblocks) )
for x,y in locs:
    div = (x/block, y/block)
    if div in zones:
        colsum = sum( pic.get_at((x,y)) )
        zones[div] += colsum

# choose best zones:
zonelist = sorted( (v,k) for k,v in zones.items() )
cut = int(xblocks * yblocks * 0.33)
bestzones = dict( (k,v) for v,k in zonelist[-cut:] )

# make segment paths:
segdrop = [(0,1)] * (block-1)
segpass = [(1,0)] * block
segloop = [(0,-1)] * (block-1) + [(1,0)] + [(0,1)] * (block-1)
segeat = ( segloop+[(1,0)] ) * (block/2)
segshort = [(1,0)] * 2 + ( segloop+[(1,0)] ) * (block/2 - 1)

def segtopath(path, seg, xdir):
    for dx,dy in seg:
        x,y = path[-1]
        newloc = (x+dx*xdir, y+dy)
        path.append(newloc)

# design good path:
xdir = 1
path = [(0,0)]
segtopath(path, segdrop, xdir)
shortzone = True
while True:
    x,y = path[-1]
    zone = (x/block, y/block)
    if zone in bestzones:
        if shortzone:
            seg = segshort
        else:
            seg = segeat
    else:
        seg = segpass
    segtopath(path, seg, xdir)
    shortzone = False
    # check end of x block run:
    x,y = path[-1]
    zone = (x/block, y/block)
    if not ( 0 <= x < xblocks*block ):
        del path[-1]
        segtopath(path, segdrop, xdir)
        shortzone = True
        xdir = xdir * -1
    if len(path) > enough:
        break
print('Path Found')

# show path on picture:
loc = path.pop(0)
eaten = 1
joetotal = grid[loc]
i = 0
while eaten <= enough:
    loc = path[i]
    i += 1
    pic.set_at(loc, (0,0,0))
    joetotal += grid[loc]
    eaten += 1
    if i % 1000 == 0:
        screen.blit(pic, (0,0))
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == QUIT: sys.exit(0)

# save picture and wait:
screen.blit(pic, (0,0))
pygame.display.flip()
pygame.image.save(pic, 'output/'+fn)
joeavg = 1.0 * joetotal/eaten
print '%s: %7.5f/%7.5f = %7.5f' % (fn, joeavg, picavg, joeavg/picavg)
while True:
    for event in pygame.event.get():
        if event.type == QUIT: sys.exit(0)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.