Autorské riešenie
[stiahni py]

  • Počet riešiteľov: 36 / 38 = 95 %

  • Úspešnosť riešenia: 4,36/6 = 72,75 %

Zadanie
V Korytnačkove pracuje korytnačka Timo, ktorá používa vzorkovník 27 farieb s ich RGB hodnotami a menom farby. Úlohou je naprogramovať funkciu zisti_farbu, ktorá pre zadané RGB hodnoty farby vráti meno farby, ktorá je k nej najbližšie. Uvažujme najprv zjednodušenú situáciu, kde sa zameriame na dva body umiestnené v rovine a až potom zistené poznatky aplikujeme na dva body umiestnené v priestore.

Vysvetlenie vzdialenosti medzi bodmi v rovine
Predstavte si, že máme dva body na papieri. Jeden bod má súradnice (x1,y1) a druhý bod má súradnice (x2,y2).

pytagorova veta usecka

Najkratšiu vzdialenosť medzi týmito bodmi môžeme vypočítať pomocou Pytagorovej vety:

pytagorova veta vzorec

pytagorova veta na obrazku

rgb model

Ak potrebujeme zistiť, ku ktorej farbe má vstupná farba najbližie, vypočítame všetky vzdialenosti medzi touto farbou a každou farbou v zozname. Ak nastane zhoda, tak vezme prvú farbu zo zoznamu.

Ak tento poznatok prenesieme do priestoru, kde body majú súradnice (x1,y1,z1) a (x2,y2,z2), môžeme v tom vidieť farby reprezentované ich RGB hodnotami. RGB hodnoty sú trojice čísel, ktoré určujú intenzitu červenej (R), zelenej (G) a modrej (B) zložky farby. Pre dve farby s RGB hodnotami (R1, G1, B1) a (R2, G2, B2) sa vzdialenosť medzi nimi vypočíta podľa vzorca:

alternatívny text k obrázku

farby       farb

Hľadáme najkratšiu vzdialenosť medzi farbou na vstupe a každou farbou zo zoznamu. V našom prípade to je 27 farieb. Najkratšiu vzdialenosť si zaznamenávame.


Príklad:

Predstavme si, že máme zadanú farbu [250,128,114] a chceme zistiť, ktorá farba zo zoznamu je jej najbližšia. Program vypočíta vzdialenosť medzi touto farbou a každou farbou v zozname. Napríklad:

  • Vzdialenosť medzi [250, 128, 114] a [255, 127, 127] je:

    sqrt((255 - 250)^2 + (127 - 128)^2 + (127 - 114)^2) = sqrt(5^2 + (-1)^2 + 13^2) = sqrt(25 + 1 + 169) = sqrt(195) = 13.96

  • Vzdialenosť medzi [250, 128, 114] a [0, 0, 0] je:

    sqrt((0 - 250)^2 + (0 - 128)^2 + (0 - 114)^2) = sqrt((-250)^2 + (-128)^2 + (-114)^2) = sqrt(62500 + 16384 + 12996) = sqrt(91880) = 303.12

Program porovná všetky tieto vzdialenosti a vyberie farbu s najmenšou vzdialenosťou, čo je v tomto prípade [255, 127, 127] s názvom "light red".

Uvedieme dve autorské riešenia tejto úlohy.

Autorské riešenie č.1:

Prvý kód definuje funkcie na výpočet vzdialenosti medzi farbami a na nájdenie najbližšieho pomenovania farby k danej farebnej hodnote RGB. Budeme potrebovať Importovanie modulu math pre použitie matematickej funkcie, ako napríklad odmocninu (sqrt), ktorá sa používa neskôr v kóde.

Funkcia vzdialenost_farieb

Vypočíta euklidovskú vzdialenosť medzi dvoma farbami v RGB priestore. Táto vzdialenosť je mierou podobnosti medzi dvoma farbami.

Funkcia zisti_farbu1

Obsahuje zoznam farieb s ich RGB hodnotami a názvami. Pre danú farbu (RGB hodnoty) nájde najbližšiu farbu zo zoznamu pomocou funkcie vzdialenost_farieb. Vráti názov najbližšej farby.

Výstup

Na konci programu je volanie funkcie zisti_farbu1 s RGB hodnotami [0, 255, 255], čo by malo vrátiť názov farby "aqua".

Užitočnosť

Tento program je užitočný na identifikáciu názvov farieb na základe ich RGB hodnôt, čo môže byť užitočné v rôznych aplikáciách, ako je grafický dizajn alebo spracovanie obrazu.


Výpočet vzdialenosti medzi farbami
- Tento kód definuje funkciu s názvom vzdialenost_farieb.
- Táto funkcia prijíma dva argumenty: farba1 a farba2, ktoré reprezentujú dve farby.
- Vypočíta vzdialenosť medzi týmito dvoma farbami v 3D farebnom priestore (pravdepodobne RGB) pomocou vzdialenostného vzorca.
- Výsledok (vzdialenosť) je potom vrátený funkciou.

Identifikácia najbližšieho názvu farby
- Tento kód definuje funkciu s názvom zisti_farbu.
- Prijíma jeden argument: farba, reprezentujúci farbu.
- Obsahuje zoznam s názvom farby_nazvy, ktorý ukladá farebné hodnoty (RGB) a ich zodpovedajúce názvy.
- Funkcia prechádza zoznamom farby_nazvy a pomocou funkcie vzdialenost_farieb vypočíta vzdialenosť medzi vstupnou farba a každou farbou v zozname.
- Sleduje farbu s najmenšou vzdialenosťou.
- Nakoniec vráti názov farby zo zoznamu farby_nazvy, ktorá je najbližšie k vstupnej farba.

Takto vyzerá kód autorského riešenia č.1:

#Python
import math


def vzdialenost_farieb(farba1, farba2):
    return math.sqrt((farba2[0] - farba1[0]) ** 2 + 
                     (farba2[1] - farba1[1]) ** 2 + 
                     (farba2[2] - farba1[2]) ** 2
                    )

def zisti_farbu1(farba):
    # doprogramuj funkciu
    farby_nazvy = [[0, 0, 0, 'black'],
                   [0, 0, 127, 'navy blue'],
                   [0, 0, 255, 'blue'],
                   [0, 127, 0, 'hulk'],
                   [0, 127, 127, 'teal'],
                   [0, 127, 255, 'azure'],
                   [0, 255, 0, 'green'],
                   [0, 255, 127, 'guppie green'],
                   [0, 255, 255, 'aqua'],
                   [127, 0, 0, 'maroon'],
                   [127, 0, 127, 'purple'],
                   [127, 0, 255, 'violent violet'],
                   [127, 127, 0, 'drably olive'],
                   [127, 127, 127, 'platinum granite'],
                   [127, 127, 255, 'blue party parrot'],
                   [127, 255, 0, 'radium'],
                   [127, 255, 127, 'light green'],
                   [127, 255, 255, 'electric blue'],
                   [255, 0, 0, 'red'],
                   [255, 0, 127, 'rose'],
                   [255, 0, 255, 'magenta'],
                   [255, 127, 0, 'orange juice'],
                   [255, 127, 127, 'light red'],
                   [255, 127, 255, 'hottest of pinks'],
                   [255, 255, 0, 'yellow'],
                   [255, 255, 127, 'ecuadorian banana'],
                   [255, 255, 255, 'white'],
                   ]

    return min(farby_nazvy, 
               key=lambda farba_nazov:vzdialenost_farieb(farba_nazov, farba))[3]

print(zisti_farbu1([250, 128, 114]))

Autorské riešenie č.2:

Toto riešenie je veľmi podobné predchádzajúcemu.

Inicializácia najmensia_vzdialenost:
Nastaví premennú najmensia_vzdialenost na nekonečno. To znamená, že každá vzdialenosť vypočítaná v nasledujúcom cykle bude menšia ako táto počiatočná hodnota.

Prechádzanie zoznamu farby_nazvy: Iteruje cez každý prvok v zozname farby_nazvy, kde každý prvok je zoznam obsahujúci RGB hodnoty a názov farby.

Výpočet vzdialenosti medzi farbami:
Používa funkciu vzdialenost_farieb na výpočet Euklidovskej vzdialenosti medzi vstupnou farbou (farba) a aktuálnou farbou v iterácii (farba_nazov).

Porovnanie vzdialeností: Ak je vypočítaná vzdialenosť menšia ako aktuálna hodnota najmensia_vzdialenost, aktualizuje najmensia_vzdialenost na túto novú menšiu vzdialenosť a uloží aktuálnu farbu ako najblizsia_farba.

Vrátenie názvu najbližšej farby:
Po skončení cyklu vráti názov farby, ktorá je najbližšie k vstupnej farbe.

Takto vyzerá kód autorského riešenia č.2:

import math


def vzdialenost_farieb(farba1, farba2):
    return math.sqrt((farba2[0] - farba1[0]) ** 2 + 
                     (farba2[1] - farba1[1]) ** 2 + 
                     (farba2[2] - farba1[2]) ** 2
                    )


def zisti_farbu(farba):
    # doprogramuj funkciu
    farby_nazvy = [[0, 0, 0, 'black'],
                   [0, 0, 127, 'navy blue'],
                   [0, 0, 255, 'blue'],
                   [0, 127, 0, 'hulk'],
                   [0, 127, 127, 'teal'],
                   [0, 127, 255, 'azure'],
                   [0, 255, 0, 'green'],
                   [0, 255, 127, 'guppie green'],
                   [0, 255, 255, 'aqua'],
                   [127, 0, 0, 'maroon'],
                   [127, 0, 127, 'purple'],
                   [127, 0, 255, 'violent violet'],
                   [127, 127, 0, 'drably olive'],
                   [127, 127, 127, 'platinum granite'],
                   [127, 127, 255, 'blue party parrot'],
                   [127, 255, 0, 'radium'],
                   [127, 255, 127, 'light green'],
                   [127, 255, 255, 'electric blue'],
                   [255, 0, 0, 'red'],
                   [255, 0, 127, 'rose'],
                   [255, 0, 255, 'magenta'],
                   [255, 127, 0, 'orange juice'],
                   [255, 127, 127, 'light red'],
                   [255, 127, 255, 'hottest of pinks'],
                   [255, 255, 0, 'yellow'],
                   [255, 255, 127, 'ecuadorian banana'],
                   [255, 255, 255, 'white'],
                   ]

    najmensia_vzdialenost = float('inf')
    for farba_nazov in farby_nazvy:
        vzdialenost = vzdialenost_farieb(farba, farba_nazov)
        if vzdialenost < najmensia_vzdialenost:
            najmensia_vzdialenost = vzdialenost
            najblizsia_farba = farba_nazov
    return najblizsia_farba[3]


print(zisti_farbu([250, 128, 114]))

Vaše zaujímavé riešenia a najčastejšie chyby

Najčastejšie chyby:
Validácia vstupných údajov: Neoverenie rozsahu (0-255) a typu (celé čísla).
Prechod reťazcom a zisťovanie režimov: Nesprávne metódy na porovnávanie farieb.
Vrátenie výsledku: Nevypisovanie alebo nevracanie názvu najbližšej farby správne.

Najlepšie riešenie:
Toto riešenie dosiahlo plný počet bodov (6 bodov) za správne implementovanie všetkých požiadaviek zadania.

import math

def orez_rgb_hodnoty(hodnota):
    return max(0, min(255, hodnota))

def zisti_farby(red, green, blue):
    
    red = orez_rgb_hodnoty(red)
    green = orez_rgb_hodnoty(green)
    blue = orez_rgb_hodnoty(blue)

    farby = [
        [0, 0, 0, 'black'],
        [0, 0, 127, 'navy blue'],
        [0, 0, 255, 'blue'],
        [0, 127, 0, 'hulk'],
        [0, 127, 127, 'teal'],
        [0, 127, 255, 'azure'],
        [0, 255, 0, 'green'],
        [0, 255, 127, 'guppie green'],
        [0, 255, 255, 'aqua'],
        [127, 0, 0, 'maroon'],
        [127, 0, 127, 'purple'],
        [127, 0, 255, 'violent violet'],
        [127, 127, 0, 'drably olive'],
        [127, 127, 127, 'platinum granite'],
        [127, 127, 255, 'blue party parrot'],
        [127, 255, 0, 'radium'],
        [127, 255, 127, 'light green'],
        [127, 255, 255, 'electric blue'],
        [255, 0, 0, 'red'],
        [255, 0, 127, 'rose'],
        [255, 0, 255, 'magenta'],
        [255, 127, 0, 'orange juice'],
        [255, 127, 127, 'light red'],
        [255, 127, 255, 'hottest of pinks'],
        [255, 255, 0, 'yellow'],
        [255, 255, 127, 'ecuadorian banana'],
        [255, 255, 255, 'white']
    ]

    najblizsia_farba = None
    najmensia_vzdialenost = float('inf')
    podobne_farby = []

    for farba in farby:
        r, g, b, nazov = farba
        vzdialenost = math.sqrt((red - r) ** 2 + 
                                (green - g) ** 2 + 
                                (blue - b) ** 2
                               )

        if vzdialenost < najmensia_vzdialenost:
            najmensia_vzdialenost = vzdialenost
            najblizsia_farba = nazov
            podobne_farby = [nazov]  
        elif vzdialenost == najmensia_vzdialenost:
            podobne_farby.append(nazov)  

    print(f"Zadané RGB hodnoty: ({red}, {green}, {blue})")
    print(f"Najbližšia farba: {najblizsia_farba}")
    if len(podobne_farby) > 1:
        print(f"Podobné farby: {', '.join(podobne_farby)}")
    else:
        print("Žiadne ďalšie podobné farby.")

    return najblizsia_farba