গিয়ে তারাকে স্টার করে দিন


14

এই প্রতিযোগিতায় আপনাকে এমন একটি প্রোগ্রাম লিখতে হবে, যা একটি কালো এবং সাদা পিক্সেল চিত্র গ্রহণ করে এবং এটির পরিবর্তনের চেষ্টা করে, যেমন সাদা আকৃতি যতটা সম্ভব পরিবর্তন সহ স্টার ডোমেন গঠন করে ।

অনুমোদিত পরিবর্তনগুলি সাদা পিক্সেলকে কালো রঙে পরিণত করছে এবং কালো পিক্সেলকে সাদা করে দিচ্ছে।

আউটপুটটিতে আবার একই চিত্র থাকতে হবে তবে এবার সমস্ত পরিবর্তন এবং একটি / কেন্দ্র চিহ্নিত রয়েছে। যে পিক্সেলগুলি সাদা থেকে কালোতে পরিবর্তিত হয়েছিল তা অবশ্যই নীলতে প্রদর্শিত হবে, যেগুলি কালো থেকে সাদাতে পরিবর্তিত হয়েছিল সেগুলি অবশ্যই হলদে প্রদর্শিত হবে এবং কমপক্ষে একটি কেন্দ্রের পিক্সেল অবশ্যই লালতে প্রদর্শিত হবে। (সুনির্দিষ্ট রঙগুলি আপনার কাছে।

সংজ্ঞা

স্টার ডোমেন

চিত্রের সাদা পিক্সেলের সেটটি একটি স্টার ডোমেনকে উপস্থাপন করে (এবং শুধুমাত্র যদি থাকে) একটি কেন্দ্র পিক্সেল থাকেকেন্দ্র পিক্সেল সাদা পিক্সেল করে একটি দ্বারা conneced যাবে এক সরল রেখা অন্যান্য সাদা পিক্সেল সব ধরনের যে লাইন শুধুমাত্র সাদা পিক্সেল ঘোরে। ( কেন্দ্রের পিক্সেল অতএব অগত্যা অনন্য নয়))

দুটি পিক্সেলের মধ্যে সোজা রেখা

দুটি পিক্সেল দেওয়া (শুরু এবং শেষ, নীচের চিত্রের মধ্যে দুটি লাল), দুটি পিক্সেলের মধ্যবর্তী স্ট্রাইথ লাইনটি সমস্ত পিক্সেল নিয়ে গঠিত, যা প্রথমটির কেন্দ্র থেকে আগত রেখাটিকে (গাণিতিক, নীচের চিত্রের মধ্যে হলুদ) স্পর্শ করে শেষ পিক্সেলের কেন্দ্রে পিক্সেল। একটি পিক্সেল কেবল কোনও কোণে স্পর্শ করে যদি লাইনটি স্পর্শ করে না , সুতরাং পিক্সেলটির জন্য পিক্সেল লাইনের সাথে সম্পর্কিত (গাণিতিক, হলুদ) রেখাটি ননজারো দৈর্ঘ্যের সাথে প্রশ্নে পিক্সেলটি অতিক্রম করতে হবে। (যদি এটি কেবল কোণার পয়েন্টকে স্পর্শ করে তবে এটি দৈর্ঘ্য শূন্য হিসাবে বিবেচিত হবে)। নিম্নলিখিত উদাহরণগুলি বিবেচনা করুন:

পিক্সেল

উদাহরণ

প্রথম চিত্রটিতে একটি উদাহরণ টেস্টকেস 'ইনপুট' উপস্থাপন করা উচিত এবং অন্য দুটি চিত্র প্রদত্ত উদাহরণের জন্য দুটি বৈধ সম্ভাব্য আউটপুট উপস্থাপন করে:

উদাহরণস্বরূপ প্রথম উদাহরণ সমাধান দ্বিতীয় উদাহরণ সমাধান

হলুদ অঞ্চলগুলি (পূর্বে কালো) 'সাদা' ডোমেনেও গণনা করা হয়, যখন নীল অঞ্চলগুলি (পূর্বে সাদা) ডোমেনের বাইরে 'কালো' অংশে গণনা করে এবং প্রতিটি সময় লাল বিন্দুতে একটি সম্ভাব্য কেন্দ্রের পিক্সেল উপস্থাপন করে।

পরীক্ষার কেস

ফলওউইং পরীক্ষার কেসগুলি প্রতিটি 256 x 256 পিক্সেলের আকারের সাথে পিএনজি হয়।

পরীক্ষার মামলা ১ পরীক্ষার কেস ২ পরীক্ষার মামলা 3 পরীক্ষার মামলা ৪ পরীক্ষার মামলা ৫ পরীক্ষার মামলা 6

স্কোরিং

নিম্নলিখিত পরীক্ষার কেসগুলি সহ আপনার প্রোগ্রামটি চালান এবং আপনার উত্তরে আউটপুট (চিত্র / পরিবর্তনের সংখ্যা) অন্তর্ভুক্ত করুন। আমি প্রতিটি পরীক্ষার ক্ষেত্রে লিডারবোর্ড তৈরি করব। আপনার স্কোর লিডারবোর্ডে প্রতিটি র‌্যাঙ্কিংয়ের যোগফল হবে - স্কোরটি আরও ভাল। স্ট্যান্ডার্ড লুফোলস প্রযোজ্য। প্রোগ্রামটিকে সেই পরীক্ষার কেসগুলি সনাক্ত করতে এবং তাদের জন্য একটি বিশেষ কেস চালানোর অনুমতি নেই is (এই পরীক্ষাগুলির প্রতিটিটির জন্য অনুকূল কেন্দ্রের পিক্সেলগুলি পূর্ববর্তী এবং সংরক্ষণ করার অনুমতি নেই)) প্রোগ্রামটি কোনও চিত্রের জন্য কাজ করা উচিত।

লিডারবোর্ড

Name        | Score | 1     - rk | 2     - rk | 3     - rk | 4     - rk | 5     - rk | 5     - rk | Total Changes
------------+-------+------------+------------+------------+------------+------------+------------+--------------
Maltysen    |    11 | 28688 -  2 | 24208 -  2 | 24248 -  1 |  7103 -  2 | 11097 -  2 | 13019 -  2 | 108363
TheBestOne  |     7 | 0     -  1 | 13698 -  1 | 24269 -  2 |   103 -  1 |  5344 -  1 |  4456 -  1 |  47867  

2
আপনি চিত্রটি ব্যাখ্যা করার জন্য এটির সাহায্য করবে 1.. আপনি উদাহরণস্বরূপ কেন লাল পিক্সেলগুলি সংযুক্ত করছেন?
ডেভিডসি

4
আমি আসলে কী বলতে চাইছি তা নিশ্চিত নই। আপনি কি আপনার পরীক্ষার কোনও মামলার আগে এবং পরে দিতে পারেন?

পিক্সেল কোণার মধ্য দিয়ে কোনও রেখাটি কতটা কাছাকাছি যেতে হবে তা বিবেচনা করার জন্য?
TheNumberOne

আমি কয়েকটি উদাহরণ যুক্ত করেছি এবং পাঠ্যটি স্পষ্ট করার চেষ্টা করেছি, আশা করি এটি এখন পরিষ্কার হয়ে গেছে!
flawr

এই চ্যালেঞ্জটি করার চেষ্টা করার মতো অন্য কেউ আছেন? আমি কিছুটা বিভ্রান্ত হয়ে পড়েছি, যেহেতু বেশ কিছু লোক এই চ্যালেঞ্জটিকে সমর্থন করেছে তবে আমরা এখন পর্যন্ত একটি মাত্র (খুব গুরুতর নয়) উত্তর পেয়েছি। কোন সমালোচনা?
flawr

উত্তর:


4

জাভা 8, 47,867 মোট পরিবর্তন।

কেন্দ্রের পয়েন্ট হিসাবে চিত্রের গড় ব্যবহার করে। এরপরে এটি সমস্ত সম্ভাব্য রশ্মিকে কেন্দ্রে আঁকে এবং এটি রঙের জন্য সেরা ব্যাসার্ধ দেয়। এটি তখন সমস্ত অবৈধ পয়েন্টকে কালো করে দেয়।

import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class MakeItStarry {

    private static final int RGB_RED = Color.RED.getRGB();
    static int[][] originalImage;

    static final int WHITE = 0;
    static final int BLACK = 1;
    static final int RGB_WHITE = Color.WHITE.getRGB();
    static final int RGB_BLACK = Color.BLACK.getRGB();
    static final int RGB_BLUE = Color.BLUE.getRGB();
    static final int RGB_YELLOW = Color.YELLOW.getRGB();

    public static void main(String[] args) throws Exception{
        originalImage = convert(ImageIO.read(new File(args[0])));
        Point center = findCenter(originalImage);
        int[][] nextImage = starry(originalImage, center);
        BufferedImage result = difference(originalImage, nextImage);
        result.setRGB(center.x, center.y, RGB_RED);
        String fileType;
        String fileName;
        if (args[1].split("\\.").length > 1){
            fileType = args[1].split("\\.")[1];
            fileName = args[1];
        } else {
            fileType = "PNG";
            fileName = args[1] + ".PNG";
        }
        ImageIO.write(result, fileType, new File(fileName));
        System.out.println(cost);
    }

    static int cost;

    private static BufferedImage difference(int[][] image1, int[][] image2) {
        cost = 0;
        int height = image1[0].length;
        int width = image1.length;
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++){
            for (int y = 0; y < width; y++){
                if (image1[x][y] == image2[x][y]){
                    if (image1[x][y] == WHITE){
                        result.setRGB(x, y, RGB_WHITE);
                    } else {
                        result.setRGB(x, y, RGB_BLACK);
                    }
                } else {
                    cost++;
                    if (image1[x][y] == WHITE){
                        result.setRGB(x, y, RGB_BLUE);
                    } else {
                        result.setRGB(x, y, RGB_YELLOW);
                    }
                }
            }
        }
        return result;
    }

    private static int[][] starry(int[][] image, Point center) {
        int width = image.length;
        int height = image[0].length;
        int[][] result = new int[width][height];
        for (int x = 0; x < width; x++){
            for (int y = 0; y < height; y++){
                result[x][y] = BLACK;
            }
        }
        for (int x = 0; x < width; x++){
            for (int y = 0; y < height; y++) {
                Point endPoint = new Point(x, y, image);
                List<Point> line = Point.lineTo(center, endPoint, image);
                List<Point> newLine = starRay(line);
                newLine.stream().filter(point -> result[point.x][point.y] == BLACK).forEach(point -> {
                    result[point.x][point.y] = point.color;
                });
            }
        }
        int distance = 0;
        while (distance < height || distance < width){//This removes pixels that can't see the center.
            for (int x = Math.max(center.x - distance,0); x < center.x + distance && x < width; x++){
                for (int y = Math.max(center.y - distance, 0); y < center.y + distance && y < height; y++){
                    Point point = new Point(x, y, result);
                    if (Point.distance(center, point) != distance){
                        continue;
                    }
                    if (point.color == WHITE){
                        List<Point> line = Point.lineTo(center, point, result);
                        for (Point p : line){
                            if (p.color == BLACK){
                                point.color = BLACK;
                                break;
                            }
                        }
                        result[point.x][point.y] = point.color;
                    }
                }
            }//All white pixels can technically see the center but only if looking from the edge.
            distance++;
        }
        return result;
    }

    private static List<Point> starRay(List<Point> line) {
        int numOfWhites = 0;
        int farthestGoodPoint = 0;
        int blackCost = 0;
        int whiteCost = 0;
        for (int i = 0; i < line.size(); i++){
            if (line.get(i).color == WHITE){
                numOfWhites++;
                whiteCost++;
                if (numOfWhites + whiteCost > blackCost){
                    blackCost = 0;
                    whiteCost = 0;
                    farthestGoodPoint = i;
                }
            } else {
                blackCost++;
                numOfWhites = 0;
            }
        }
        List<Point> result = new ArrayList<>();
        for (int i = 0; i < line.size(); i++){
            Point p = line.get(i);
            if (i <= farthestGoodPoint){
                result.add(new Point(p.x, p.y, WHITE));
            } else {
                result.add(new Point(p.x, p.y, BLACK));
            }
        }
        return result;
    }

    private static Point findCenter(int[][] image) {
        double totalx = 0;
        double totaly = 0;
        int counter = 0;
        int width = image.length;
        int height = image[0].length;
        for (int x = 0; x < width; x++){
            for (int y = 0; y < height; y++){
                if (image[x][y] == WHITE){
                    totalx += x;
                    totaly += y;
                    counter++;
                }
            }
        }
        return new Point((int)(totalx/counter), (int)(totaly/counter), image);
    }

    private static int[][] convert(BufferedImage image) {
        int width = image.getWidth();
        int height  = image.getHeight();
        int[][] result = new int[width][height];
        for (int x = 0; x < width; x++){
            for (int y = 0; y < height; y++){
                if (image.getRGB(x, y) == RGB_WHITE){
                    result[x][y] = WHITE;
                } else {
                    result[x][y] = BLACK;
                }
            }
        }
        return result;
    }


    private static class Point {

        public int color;
        public int y;
        public int x;

        public Point(int x, int y, int[][] image) {
            this.x = x;
            this.y = y;
            this.color = image[x][y];
        }

        public Point(int x, int y, int color) {
            this.x = x;
            this.y = y;
            this.color = color;
        }

        public static List<Point> lineTo(Point point1, Point point2, int[][] image) {
            List<Point> result = new ArrayList<>();
            boolean reversed = false;
            if (point1.x > point2.x){
                Point buffer = point1;
                point1 = point2;
                point2 = buffer;
                reversed = !reversed;
            }
            int rise = point1.y - point2.y;
            int run = point1.x - point2.x;
            if (run == 0){
                if (point1.y > point2.y){
                    Point buffer = point1;
                    point1 = point2;
                    point2 = buffer;
                    reversed = !reversed;
                }
                int x = point1.x;
                for (int y = point1.y; y <= point2.y; y++){
                    result.add(new Point(x, y, image));
                }
                if (reversed){
                    return reversed(result);
                }
                return result;
            }
            if (rise == 0){
                if (point1.x > point2.x){
                    Point buffer = point1;
                    point1 = point2;
                    point2 = buffer;
                    reversed = !reversed;
                }
                int y = point1.y;
                for (int x = point1.x; x <= point2.x; x++){
                    result.add(new Point(x, y, image));
                }
                if (reversed){
                    return reversed(result);
                }
                return result;
            }
            int gcd = gcd(rise, run);
            rise /= gcd;
            run /= gcd;
            double slope = (rise + 0.0) / run;
            if (Math.abs(rise) >= Math.abs(run)){
                if (point1.y > point2.y){
                    Point buffer = point1;
                    point1 = point2;
                    point2 = buffer;
                    reversed = !reversed;
                }
                double x = point1.x;
                for (double y = point1.y + .5; y <= point2.y; y++){
                    int px = (int) Math.round(x);
                    if (Math.abs(Math.abs(px - x) - .5) < Math.abs(1.0 / (rise * 4))){
                        x += 1/slope;
                        continue;
                    }
                    result.add(new Point(px, (int) Math.round(y - .5), image));
                    result.add(new Point(px, (int) Math.round(y + .5), image));
                    x += 1/slope;
                }
                if (reversed){
                    return reversed(result);
                }
                return result;
            } else {
                if (point1.x > point2.x){
                    Point buffer = point1;
                    point1 = point2;
                    point2 = buffer;
                    reversed = !reversed;
                }
                double y = point1.y;
                for (double x = point1.x + .5; x <= point2.x; x++){
                    int py = (int) Math.round(y);
                    if (Math.abs(Math.abs(py - y) - .5) < Math.abs(1.0 / (run * 4))) {
                        y += slope;
                        continue;
                    }
                    result.add(new Point((int) Math.round(x - .5), py, image));
                    result.add(new Point((int) Math.round(x + .5), py, image));
                    y += slope;
                }
                if (reversed){
                    return reversed(result);
                }
                return result;
            }
        }

        private static List<Point> reversed(List<Point> points) {
            List<Point> result = new ArrayList<>();
            for (int i = points.size() - 1; i >= 0; i--){
                result.add(points.get(i));
            }
            return result;
        }

        private static int gcd(int num1, int num2) {
            if (num1 < 0 && num2 < 0){
                return -gcd(-num1, -num2);
            }
            if (num1 < 0){
                return gcd(-num1, num2);
            }
            if (num2 < 0){
                return gcd(num1, -num2);
            }
            if (num2 > num1){
                return gcd(num2, num1);
            }
            if (num2 == 0){
                return num1;
            }
            return gcd(num2, num1 % num2);
        }

        @Override
        public String toString(){
            return x + " " + y;
        }

        public static int distance(Point point1, Point point2) {
            return Math.abs(point1.x - point2.x) + Math.abs(point1.y - point2.y);
        }
    }
}

ফলাফল

চিত্র 1 - 0 টি পরিবর্তন, চিত্র 2 - 13,698 টি পরিবর্তন

12

চিত্র 3 - 24,269 পরিবর্তন, চিত্র 4 - 103 পরিবর্তন

34

চিত্র 5 - 5,344 পরিবর্তন, চিত্র 6 - 4,456 পরিবর্তন

56

অবৈধ পিক্সেল সরানো ছাড়া, মোট 42,782 টি পরিবর্তন changes

সবুজ পিক্সেলগুলি অবৈধ পিক্সেলের প্রথম স্তর।

চিত্র 1 - 0 টি পরিবর্তন, চিত্র 2- 9,889 টি পরিবর্তন

12

চিত্র 3 - 24,268 পরিবর্তন, চিত্র 4 - 103 পরিবর্তন

34

চিত্র 5 - 4,471 পরিবর্তন, চিত্র 6- 4,050 পরিবর্তন

56

সমস্ত ছবিতে সমস্ত সাদা পিক্সেলগুলির মধ্য পিক্সেল থেকে তাদের কাছে একটি লাইন আঁকা থাকতে পারে যদি লাইনটি কেন্দ্রগুলিতে উত্পন্ন / শেষ করতে না হয় তবে পিক্সেলের যে কোনও জায়গায়।

args[0] ইনপুট ফাইলের নাম ধারণ করে।

args[1] আউটপুট ফাইলের নাম ধারণ করে।

stdoutপরিবর্তন সংখ্যা প্রিন্ট ।


দুর্দান্ত লাগছে! আপনি 'অবৈধ পিক্সেল' বলতে কী বোঝাতে চান? আমি বেশ বুঝতে পারিনি। নীচে ডানদিকে 2 ইমেজটিতেও আমি অনুসরণ করতে পারিনি কেন আপনার প্রোগ্রামটি 'কালো রঙের প্রাচীরে' খনন করে তবে তারপরেও আবার সাদা বিন্দুগুলিকে আবার কালো রঙ করে, তবে আমি মনে করি এটি 'অবৈধ পিক্সেল'-এর সাথে করা উচিত?
flawr

কয়েকটি অকার্যকর পিক্সেল একটি ক্যাসকেড প্রভাবের কারণ করে যা আরও অনেকগুলি অবৈধ করে তোলে। অবৈধ পিক্সেলের প্রথম স্তরটিকে সবুজ হিসাবে দেখানোর জন্য আমি শেষ কয়েকটি চিত্র পরিবর্তন করব।
TheNumberOne

3

পাইথন - পিআইএল - মোট 216,228 108,363 টি পরিবর্তন

ছিঃ! @ আজম্যান্সফিল্ডকে অর্ধেক ধন্যবাদ দিয়ে এটি কেটে দিন! এই অ্যালগরিদম গণনাকারী লাইন এবং অপ্টিমাইজেশান এবং কী না তা নিয়ে সমস্ত উদ্বেগজনক বিষয় এড়িয়ে চলে। এটি কেবল একটি বাদে সমস্ত সাদাকে কালো করে দেয়। যদি কোনও শ্বেতা না থাকে তবে এটি একটি কালোকে সাদা করে তোলে। এটি আরও বেশি সাদা বা কালো আছে কিনা তা পরীক্ষা করে দেখায় এবং অন্য একটিকে বাদে অন্য ধরণের একটিকে পরিবর্তিত করে। যদি কোনও কালো না থাকে তবে এটি (0, 0) কেন্দ্র করে।

import Image
from itertools import product

img = Image.open(raw_input())
img = img.convert("RGB")

pixdata = img.load()
changed=0

m=False
count=0
for x, y in product(xrange(img.size[1]), xrange(img.size[0])):
    if pixdata[x, y]==(0, 0, 0):
        count+=1

colors=[(0, 0, 0), (255, 255, 0)] if img.size[0]*img.size[1]-count>count else [(255, 255, 255), (0, 0, 255)]
m=False
for x, y in product(xrange(img.size[1]), xrange(img.size[0])):
    if pixdata[x, y] == colors[0]:
        if m:
            pixdata[x, y] = colors[1]
        else:
            pixdata[x, y] = (255, 0, 0)
            m=True
        changed+=1

if not m:
    pixdata[0, 0]==(255, 0, 0)
    changed+=1
if colors[0]==(255, 255, 255):
    changed-=1

print changed
img.save("out.png", "PNG")

ফলাফল

চিত্র 1 - 28688 পরিবর্তন, চিত্র 2 - 24208 পরিবর্তন

চিত্র 3 - 24248 পরিবর্তন, চিত্র 4 - 7103 পরিবর্তন

চিত্র 5 - 11097 পরিবর্তন, চিত্র 6 - 13019 পরিবর্তন

কাঁচা-ইনপুট থেকে ফাইলের নাম নেয় এবং আউট.পিএনজি থেকে লেখেন এবং পরিবর্তনের সংখ্যা মুদ্রণ করেন।


নোট করুন যে পিক্সেলগুলি কালো থেকে সাদাতে পরিবর্তিত হয়েছিল তা আপনার আউটপুটে হলুদ হওয়া উচিত। যেগুলি সাদা থেকে কালোতে পরিবর্তিত হয়েছিল সেগুলি নীল হতে হবে এবং কেন্দ্রটি (আপনার ক্ষেত্রে আপনার একমাত্র 'সাদা' পিক্সেলটি আপনার আউটপুটে লাল হওয়া উচিত than এ ছাড়া অংশ নেওয়ার জন্য আপনাকে ধন্যবাদ =) পিএস: এটি সর্বদা সম্ভব হওয়া উচিত স্টার ডোমেন তৈরি করুন, এমনকি আপনার যখন ইনপুট হিসাবে পুরো কালো চিত্র থাকে তখনও আপনি একটি পিক্সেলকে সাদা (লাল) করতে পারেন।
flawr

সাদা বা কালো পিক্সেল (অর্থাত্ পূর্ণ বর্ণ) না থাকলে এটি অসম্ভব হতে পারে । যে কোনও ক্ষেত্রে আমি অন্যান্য পরিবর্তনগুলি করছি।
মালটিসেন

উহু. কালো এবং সাদা চিত্র। আমার খারাপ।
মালটিসেন

আমি মনে করি বিপরীত কৌশলটি করা আরও দক্ষ হতে পারে এবং সমস্ত কালো পিক্সেলকে সাদাতে পরিবর্তন করতে পারে। তুমি কি চেষ্টা করেছ?
জে ম্যানসফিল্ড

@ এজেম্যান্সফিল্ড আমার মনে হয় প্রদত্ত পরীক্ষার ক্ষেত্রে এটি কেবল আরও কার্যকর হবে, সুতরাং সম্ভবত এটি ইতিমধ্যে প্রদত্ত টেস্টকেসগুলির জন্য অ্যালগরিদমকে কন্ডিশনার হিসাবে বিবেচনা করা যেতে পারে।
flawr
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.