• 08-01-2022, 13:01:28
    #1
    Merhaba,
    Aradığım program şöyle;

    iki farklı veri örneğin; sayi_miktar ve sayi_oran
    bu verilerden kaç tane varsa hepsi MySQL den çekilecek. Bu örnekte 5 tane çekilmiş olsun.

    sayi_miktar - sayi_oran

    2500 - 13
    4000 - 13
    3500 - 15
    1000 - 14
    2500 - 13

    bu çekilen tüm verileri karşılaştıracak ve sıraya sokacak bir sisteme ihtiyacım var
    Kural: sayi_oran'ı büyük olan her zaman öncelikli. Eğer sayi_oran eşitse sayi_miktar büyük olan öncelikli. İkisi de eşitse eşit miktarda işlem görecek.

    Sıra neden önemli ? Çünkü sistemin sabit bir sayısı var mesela 10.000 olsun. Sıraya göre sayi_miktar'lar bu sayıdan çıkarılacak.

    1.Adım:
    10.000 - 3500 = 6500

    2.Adım
    6500 - 1000 = 5500

    3.Adım
    5500 - 4000 = 1500

    4.Adım
    1500 - 750 = 750

    5.Adım
    750 - 750 = 0

    4. ve 5. Adımlarda 750 alındı çünkü eşit alınması gerekiyor ve baştaki sabit sayı (10.000) 0 a düşünce sistem durmalı. 4. Adımda 2500/2 = 1250 alınsaydı 5. Adımda sadece 250 kalırdı ve son ikiye kalan veriler eşit paylaşılmazdı.

    Bu programı nasıl yazabilirim ?
    Yardımcı olabilecek herkese teşekkürler.
  • 08-01-2022, 13:07:52
    #2
    "Eğer sayi_oran eşitse sayi_miktar büyük olan öncelikli." İkside eşitse büyük olanı nasıl bulabiliriz sanırım anlamadım daha detaylı bir şekilde anlatabilir misiniz?
  • 08-01-2022, 13:19:31
    #3
    cloudguy adlı üyeden alıntı: mesajı görüntüle
    "Eğer sayi_oran eşitse sayi_miktar büyük olan öncelikli." İkside eşitse büyük olanı nasıl bulabiliriz sanırım anlamadım daha detaylı bir şekilde anlatabilir misiniz?
    sayi_oran eşitse sayi_miktar büyük olan öncelikli yani;

    1500 - 15
    1750 - 15
    gibi bir durumda ilk -1750 çıkarılacak sonra -1500 çıkarılacak

    sayi_oran ve sayi_miktar eşitse, ikisinden de eşit miktarda alınacak. sayi_miktarları ikiye bölünüp ana sayıdan çıkarılacak yani;

    2000 - 17
    2000 - 17
    gibi bir durumda ikisinden de 1000 er alınıp çıkarılacak. Ama burda bir sıkıntı daha var, ana sayıdan geriye sadece 800 kalmış olabilir. Bu durumda -400 -400 şeklinde yine ikisinden de eşit miktarda alınacak

    sayi_miktar eşitse sayi_oran büyük olan işleme girecek yani;
    4000 - 14
    4000 - 15
    gibi bir durumda ilk önce alttaki veriden -4000 alınacak sonra üsttekinden -4000 alınacak.
  • 08-01-2022, 16:16:25
    #4
    Muhtemelen tam olarak çalışıyor olması lazım. Biraz sinirimi bozdu ama keyifliydi Kolay gelsin.

    // dağıtılacak sayı
    $num = 10000;
    
    $array = [
    
        ['sayi_miktar' => 2500, 'sayi_oran' => 13],
        ['sayi_miktar' => 4000, 'sayi_oran' => 13],
        ['sayi_miktar' => 3500, 'sayi_oran' => 15],
        ['sayi_miktar' => 1000, 'sayi_oran' => 14],
        ['sayi_miktar' => 2500, 'sayi_oran' => 13],
    ];
    
    usort($array, function($a, $b){
        if($a['sayi_oran'] == $b['sayi_oran'])
            return $a['sayi_miktar'] < $b['sayi_miktar'];
        return $a['sayi_oran'] < $b['sayi_oran'];
    });
    
    $array = array_map(function($i) use($array){
        $f = array_filter($array, function($a) use($i){
            return $a['sayi_miktar'] == $i['sayi_miktar'] && $a['sayi_oran'] == $i['sayi_oran'];
        });
        return count($f) > 1 ? array_merge($i, ['esit' => count($f), 'varsay' => $i['sayi_miktar']/count($f)]) : $i;
    }, $array);
    
    $log = [];
    $end = false;
    
    foreach ($array as $k => $a) {
    
        $prev = $num;
    
        if($end){
            $calc = $end;
        } else{
            if(isset($a['esit'])){
                if($num < $a['sayi_miktar']){
                    $calc = $end = $num/$a['esit'];
                } else{
                    $calc = $a['varsay'];
                }
            } else{
                $calc = $num < $a['sayi_miktar'] ? $num : $a['sayi_miktar'];
            }
        }
    
        $num -= $calc;
    
        if($calc <= 0 ||$num < 0) break;
    
        $log[] = [
            'adim' => $k+1,
            'oran' => $a['sayi_oran'],
            'miktar' => $a['sayi_miktar'],
            'islem' => $prev.'-'.$calc,
            'cikan' => $calc,
            'kalan' => $num
        ];
    }
    
    print_r($log);
    Array
    (
        [0] => Array
        (
            [adim] => 1
            [oran] => 15
            [miktar] => 3500
            [islem] => 10000-3500
            [cikan] => 3500
            [kalan] => 6500
        )
        [1] => Array
        (
            [adim] => 2
            [oran] => 14
            [miktar] => 1000
            [islem] => 6500-1000
            [cikan] => 1000
            [kalan] => 5500
        )
        [2] => Array
        (
            [adim] => 3
            [oran] => 13
            [miktar] => 4000
            [islem] => 5500-4000
            [cikan] => 4000
            [kalan] => 1500
        )
        [3] => Array
        (
            [adim] => 4
            [oran] => 13
            [miktar] => 2500
            [islem] => 1500-750
            [cikan] => 750
            [kalan] => 750
        )
        [4] => Array
        (
            [adim] => 5
            [oran] => 13
            [miktar] => 2500
            [islem] => 750-750
            [cikan] => 750
            [kalan] => 0
        )
    )
  • 08-01-2022, 17:03:26
    #5
    ghergedan adlı üyeden alıntı: mesajı görüntüle
    Muhtemelen tam olarak çalışıyor olması lazım. Biraz sinirimi bozdu ama keyifliydi Kolay gelsin.

    // dağıtılacak sayı
    $num = 10000;
    
    $array = [
    
        ['sayi_miktar' => 2500, 'sayi_oran' => 13],
        ['sayi_miktar' => 4000, 'sayi_oran' => 13],
        ['sayi_miktar' => 3500, 'sayi_oran' => 15],
        ['sayi_miktar' => 1000, 'sayi_oran' => 14],
        ['sayi_miktar' => 2500, 'sayi_oran' => 13],
    ];
    
    usort($array, function($a, $b){
        if($a['sayi_oran'] == $b['sayi_oran'])
            return $a['sayi_miktar'] < $b['sayi_miktar'];
        return $a['sayi_oran'] < $b['sayi_oran'];
    });
    
    $array = array_map(function($i) use($array){
        $f = array_filter($array, function($a) use($i){
            return $a['sayi_miktar'] == $i['sayi_miktar'] && $a['sayi_oran'] == $i['sayi_oran'];
        });
        return count($f) > 1 ? array_merge($i, ['esit' => count($f), 'varsay' => $i['sayi_miktar']/count($f)]) : $i;
    }, $array);
    
    $log = [];
    $end = false;
    
    foreach ($array as $k => $a) {
    
        $prev = $num;
    
        if($end){
            $calc = $end;
        } else{
            if(isset($a['esit'])){
                if($num < $a['sayi_miktar']){
                    $calc = $end = $num/$a['esit'];
                } else{
                    $calc = $a['varsay'];
                }
            } else{
                $calc = $num < $a['sayi_miktar'] ? $num : $a['sayi_miktar'];
            }
        }
    
        $num -= $calc;
    
        if($calc <= 0 ||$num < 0) break;
    
        $log[] = [
            'adim' => $k+1,
            'oran' => $a['sayi_oran'],
            'miktar' => $a['sayi_miktar'],
            'islem' => $prev.'-'.$calc,
            'cikan' => $calc,
            'kalan' => $num
        ];
    }
    
    print_r($log);
    Array
    (
        [0] => Array
        (
            [adim] => 1
            [oran] => 15
            [miktar] => 3500
            [islem] => 10000-3500
            [cikan] => 3500
            [kalan] => 6500
        )
        [1] => Array
        (
            [adim] => 2
            [oran] => 14
            [miktar] => 1000
            [islem] => 6500-1000
            [cikan] => 1000
            [kalan] => 5500
        )
        [2] => Array
        (
            [adim] => 3
            [oran] => 13
            [miktar] => 4000
            [islem] => 5500-4000
            [cikan] => 4000
            [kalan] => 1500
        )
        [3] => Array
        (
            [adim] => 4
            [oran] => 13
            [miktar] => 2500
            [islem] => 1500-750
            [cikan] => 750
            [kalan] => 750
        )
        [4] => Array
        (
            [adim] => 5
            [oran] => 13
            [miktar] => 2500
            [islem] => 750-750
            [cikan] => 750
            [kalan] => 0
        )
    )
    Çok teşekkürler baya işime yaradı.
    Elinize sağlık.

    Test ederken bir sıkıntı fark ettim.
    // dağıtılacak sayı
    $num = 3500;
    
    $array = [
     
        ['sayi_miktar' => 2500, 'sayi_oran' => 15],
        ['sayi_miktar' => 1000, 'sayi_oran' => 13],
        ['sayi_miktar' => 1000, 'sayi_oran' => 13],
      
    ];
    böyle bi veri girişi yaptığımda, dağıtılacak sayının tam 0 olması gerekiyordu.
    oran 15 olandan -2500; 13 olanlardan ise -500 -500 alıp 0 olması lazım. Ama sonuç böyle çıkıyor.

    Array ( [0] => Array ( [adim] => 1 [oran] => 15 [miktar] => 2500 [islem] => 3500-2500 [cikan] => 2500 [kalan] => 1000 ) [1] => Array ( [adim] => 2 [oran] => 13 [miktar] => 1000 [islem] => 1000-500 [cikan] => 500 [kalan] => 500 ) [2] => Array ( [adim] => 3 [oran] => 13 [miktar] => 1000 [islem] => 500-250 [cikan] => 250 [kalan] => 250 ) )
  • 09-01-2022, 08:49:41
    #6
    ozcaglarbora adlı üyeden alıntı: mesajı görüntüle
    Çok teşekkürler baya işime yaradı.
    Elinize sağlık.

    Test ederken bir sıkıntı fark ettim.
    // dağıtılacak sayı
    $num = 3500;
    
    $array = [
     
        ['sayi_miktar' => 2500, 'sayi_oran' => 15],
        ['sayi_miktar' => 1000, 'sayi_oran' => 13],
        ['sayi_miktar' => 1000, 'sayi_oran' => 13],
      
    ];
    böyle bi veri girişi yaptığımda, dağıtılacak sayının tam 0 olması gerekiyordu.
    oran 15 olandan -2500; 13 olanlardan ise -500 -500 alıp 0 olması lazım. Ama sonuç böyle çıkıyor.

    Array ( [0] => Array ( [adim] => 1 [oran] => 15 [miktar] => 2500 [islem] => 3500-2500 [cikan] => 2500 [kalan] => 1000 ) [1] => Array ( [adim] => 2 [oran] => 13 [miktar] => 1000 [islem] => 1000-500 [cikan] => 500 [kalan] => 500 ) [2] => Array ( [adim] => 3 [oran] => 13 [miktar] => 1000 [islem] => 500-250 [cikan] => 250 [kalan] => 250 ) )
    37. satırı şununla değiştirin;
    if($num <= $a['sayi_miktar']){